@webiny/api-file-manager-s3 0.0.0-unstable.eb196ccd2f → 0.0.0-unstable.eb81deee7e

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 (232) hide show
  1. package/FileManagerS3Feature.d.ts +9 -0
  2. package/FileManagerS3Feature.js +27 -0
  3. package/FileManagerS3Feature.js.map +1 -0
  4. package/README.md +11 -1
  5. package/assetDelivery/abstractions.d.ts +11 -0
  6. package/assetDelivery/abstractions.js +7 -0
  7. package/assetDelivery/abstractions.js.map +1 -0
  8. package/assetDelivery/assetDeliveryConfig.d.ts +2 -2
  9. package/assetDelivery/assetDeliveryConfig.js +10 -49
  10. package/assetDelivery/assetDeliveryConfig.js.map +1 -1
  11. package/assetDelivery/createAssetDelivery.d.ts +3 -3
  12. package/assetDelivery/createAssetDelivery.js +7 -28
  13. package/assetDelivery/createAssetDelivery.js.map +1 -1
  14. package/assetDelivery/feature.d.ts +5 -0
  15. package/assetDelivery/feature.js +36 -0
  16. package/assetDelivery/feature.js.map +1 -0
  17. package/assetDelivery/index.d.ts +8 -9
  18. package/assetDelivery/index.js +8 -70
  19. package/assetDelivery/s3/LazySharpTransform.d.ts +34 -0
  20. package/assetDelivery/s3/LazySharpTransform.js +34 -0
  21. package/assetDelivery/s3/LazySharpTransform.js.map +1 -0
  22. package/assetDelivery/s3/S3AssetResolver.d.ts +9 -4
  23. package/assetDelivery/s3/S3AssetResolver.js +34 -32
  24. package/assetDelivery/s3/S3AssetResolver.js.map +1 -1
  25. package/assetDelivery/s3/S3ContentsReader.d.ts +1 -3
  26. package/assetDelivery/s3/S3ContentsReader.js +12 -22
  27. package/assetDelivery/s3/S3ContentsReader.js.map +1 -1
  28. package/assetDelivery/s3/S3ErrorAssetReply.js +11 -17
  29. package/assetDelivery/s3/S3ErrorAssetReply.js.map +1 -1
  30. package/assetDelivery/s3/S3OutputStrategy.d.ts +6 -6
  31. package/assetDelivery/s3/S3OutputStrategy.js +35 -35
  32. package/assetDelivery/s3/S3OutputStrategy.js.map +1 -1
  33. package/assetDelivery/s3/S3RedirectAssetReply.js +14 -20
  34. package/assetDelivery/s3/S3RedirectAssetReply.js.map +1 -1
  35. package/assetDelivery/s3/S3StreamAssetReply.js +14 -20
  36. package/assetDelivery/s3/S3StreamAssetReply.js.map +1 -1
  37. package/assetDelivery/s3/SharpTransform.d.ts +22 -14
  38. package/assetDelivery/s3/SharpTransform.js +163 -182
  39. package/assetDelivery/s3/SharpTransform.js.map +1 -1
  40. package/assetDelivery/s3/transformation/AssetKeyGenerator.js +17 -25
  41. package/assetDelivery/s3/transformation/AssetKeyGenerator.js.map +1 -1
  42. package/assetDelivery/s3/transformation/CallableContentsReader.d.ts +0 -2
  43. package/assetDelivery/s3/transformation/CallableContentsReader.js +7 -13
  44. package/assetDelivery/s3/transformation/CallableContentsReader.js.map +1 -1
  45. package/assetDelivery/s3/transformation/WidthCollection.js +14 -22
  46. package/assetDelivery/s3/transformation/WidthCollection.js.map +1 -1
  47. package/assetDelivery/s3/transformation/utils.d.ts +1 -3
  48. package/assetDelivery/s3/transformation/utils.js +26 -28
  49. package/assetDelivery/s3/transformation/utils.js.map +1 -1
  50. package/assetDelivery/threatDetection/ObjectKey.d.ts +7 -0
  51. package/assetDelivery/threatDetection/ObjectKey.js +18 -0
  52. package/assetDelivery/threatDetection/ObjectKey.js.map +1 -0
  53. package/assetDelivery/threatDetection/createThreatDetectionEventHandler.d.ts +22 -2
  54. package/assetDelivery/threatDetection/createThreatDetectionEventHandler.js +49 -58
  55. package/assetDelivery/threatDetection/createThreatDetectionEventHandler.js.map +1 -1
  56. package/assetDelivery/threatDetection/createThreatDetectionPluginLoader.d.ts +1 -1
  57. package/assetDelivery/threatDetection/createThreatDetectionPluginLoader.js +3 -11
  58. package/assetDelivery/threatDetection/createThreatDetectionPluginLoader.js.map +1 -1
  59. package/assetDelivery/threatDetection/index.d.ts +2 -2
  60. package/assetDelivery/threatDetection/index.js +2 -29
  61. package/assetDelivery/threatDetection/processThreatScanResult.d.ts +3 -2
  62. package/assetDelivery/threatDetection/processThreatScanResult.js +56 -61
  63. package/assetDelivery/threatDetection/processThreatScanResult.js.map +1 -1
  64. package/assetDelivery/threatDetection/types.d.ts +0 -4
  65. package/assetDelivery/threatDetection/types.js +0 -7
  66. package/assetDelivery/types.d.ts +4 -2
  67. package/assetDelivery/types.js +0 -7
  68. package/enterprise/ApplyThreatScanning/CreateFileWithThreatScanDecorator.d.ts +13 -0
  69. package/enterprise/ApplyThreatScanning/CreateFileWithThreatScanDecorator.js +28 -0
  70. package/enterprise/ApplyThreatScanning/CreateFileWithThreatScanDecorator.js.map +1 -0
  71. package/enterprise/ApplyThreatScanning/feature.d.ts +4 -0
  72. package/enterprise/ApplyThreatScanning/feature.js +11 -0
  73. package/enterprise/ApplyThreatScanning/feature.js.map +1 -0
  74. package/features/DeleteFileFromBucket/DeleteFileFromBucketHandler.d.ts +15 -0
  75. package/features/DeleteFileFromBucket/DeleteFileFromBucketHandler.js +35 -0
  76. package/features/DeleteFileFromBucket/DeleteFileFromBucketHandler.js.map +1 -0
  77. package/features/DeleteFileFromBucket/DeleteS3FolderTask.d.ts +37 -0
  78. package/features/DeleteFileFromBucket/DeleteS3FolderTask.js +57 -0
  79. package/features/DeleteFileFromBucket/DeleteS3FolderTask.js.map +1 -0
  80. package/features/DeleteFileFromBucket/feature.d.ts +4 -0
  81. package/features/DeleteFileFromBucket/feature.js +13 -0
  82. package/features/DeleteFileFromBucket/feature.js.map +1 -0
  83. package/features/ExtractMetadata/ExtractMetadataHandler.d.ts +11 -0
  84. package/features/ExtractMetadata/ExtractMetadataHandler.js +25 -0
  85. package/features/ExtractMetadata/ExtractMetadataHandler.js.map +1 -0
  86. package/features/ExtractMetadata/ExtractMetadataTask.d.ts +29 -0
  87. package/features/ExtractMetadata/ExtractMetadataTask.js +99 -0
  88. package/features/ExtractMetadata/ExtractMetadataTask.js.map +1 -0
  89. package/features/ExtractMetadata/feature.d.ts +4 -0
  90. package/features/ExtractMetadata/feature.js +13 -0
  91. package/features/ExtractMetadata/feature.js.map +1 -0
  92. package/features/FlushCache/FlushCacheOnFileDeleteHandler.d.ts +12 -0
  93. package/features/FlushCache/FlushCacheOnFileDeleteHandler.js +28 -0
  94. package/features/FlushCache/FlushCacheOnFileDeleteHandler.js.map +1 -0
  95. package/features/FlushCache/FlushCacheOnFileUpdateHandler.d.ts +12 -0
  96. package/features/FlushCache/FlushCacheOnFileUpdateHandler.js +31 -0
  97. package/features/FlushCache/FlushCacheOnFileUpdateHandler.js.map +1 -0
  98. package/features/FlushCache/InvalidateCacheTask.d.ts +31 -0
  99. package/features/FlushCache/InvalidateCacheTask.js +84 -0
  100. package/features/FlushCache/InvalidateCacheTask.js.map +1 -0
  101. package/features/FlushCache/feature.d.ts +4 -0
  102. package/features/FlushCache/feature.js +15 -0
  103. package/features/FlushCache/feature.js.map +1 -0
  104. package/features/GetFileContentsById/GetFileContentsByIdUseCase.d.ts +13 -0
  105. package/features/GetFileContentsById/GetFileContentsByIdUseCase.js +40 -0
  106. package/features/GetFileContentsById/GetFileContentsByIdUseCase.js.map +1 -0
  107. package/features/GetFileContentsById/feature.d.ts +4 -0
  108. package/features/GetFileContentsById/feature.js +11 -0
  109. package/features/GetFileContentsById/feature.js.map +1 -0
  110. package/features/GetFileContentsByKey/GetFileContentsByKeyUseCase.d.ts +13 -0
  111. package/features/GetFileContentsByKey/GetFileContentsByKeyUseCase.js +40 -0
  112. package/features/GetFileContentsByKey/GetFileContentsByKeyUseCase.js.map +1 -0
  113. package/features/GetFileContentsByKey/feature.d.ts +4 -0
  114. package/features/GetFileContentsByKey/feature.js +11 -0
  115. package/features/GetFileContentsByKey/feature.js.map +1 -0
  116. package/features/WriteFileMetadata/MetadataReader.d.ts +14 -0
  117. package/features/WriteFileMetadata/MetadataReader.js +13 -0
  118. package/features/WriteFileMetadata/MetadataReader.js.map +1 -0
  119. package/features/WriteFileMetadata/MetadataWriter.d.ts +10 -0
  120. package/features/WriteFileMetadata/MetadataWriter.js +28 -0
  121. package/features/WriteFileMetadata/MetadataWriter.js.map +1 -0
  122. package/features/WriteFileMetadata/WriteMetadataAfterBatchCreateHandler.d.ts +12 -0
  123. package/features/WriteFileMetadata/WriteMetadataAfterBatchCreateHandler.js +23 -0
  124. package/features/WriteFileMetadata/WriteMetadataAfterBatchCreateHandler.js.map +1 -0
  125. package/features/WriteFileMetadata/WriteMetadataAfterCreateHandler.d.ts +12 -0
  126. package/features/WriteFileMetadata/WriteMetadataAfterCreateHandler.js +25 -0
  127. package/features/WriteFileMetadata/WriteMetadataAfterCreateHandler.js.map +1 -0
  128. package/features/WriteFileMetadata/feature.d.ts +4 -0
  129. package/features/WriteFileMetadata/feature.js +13 -0
  130. package/features/WriteFileMetadata/feature.js.map +1 -0
  131. package/graphql/S3GraphQLSchema.d.ts +10 -0
  132. package/graphql/S3GraphQLSchema.js +233 -0
  133. package/graphql/S3GraphQLSchema.js.map +1 -0
  134. package/graphql/checkPermissions.d.ts +5 -0
  135. package/graphql/checkPermissions.js +22 -0
  136. package/graphql/checkPermissions.js.map +1 -0
  137. package/index.d.ts +4 -5
  138. package/index.js +3 -36
  139. package/multiPartUpload/CompleteMultiPartUploadUseCase.d.ts +1 -1
  140. package/multiPartUpload/CompleteMultiPartUploadUseCase.js +49 -59
  141. package/multiPartUpload/CompleteMultiPartUploadUseCase.js.map +1 -1
  142. package/multiPartUpload/CreateMultiPartUploadUseCase.d.ts +2 -2
  143. package/multiPartUpload/CreateMultiPartUploadUseCase.js +30 -44
  144. package/multiPartUpload/CreateMultiPartUploadUseCase.js.map +1 -1
  145. package/package.json +36 -34
  146. package/types.d.ts +2 -1
  147. package/types.js +1 -7
  148. package/utils/CdnPathsGenerator.d.ts +3 -0
  149. package/utils/CdnPathsGenerator.js +11 -0
  150. package/utils/CdnPathsGenerator.js.map +1 -0
  151. package/utils/FileExtension.d.ts +1 -1
  152. package/utils/FileExtension.js +11 -19
  153. package/utils/FileExtension.js.map +1 -1
  154. package/utils/FileKey.d.ts +1 -1
  155. package/utils/FileKey.js +29 -29
  156. package/utils/FileKey.js.map +1 -1
  157. package/utils/FileKey.test.js +50 -51
  158. package/utils/FileKey.test.js.map +1 -1
  159. package/utils/FileNormalizer.d.ts +2 -2
  160. package/utils/FileNormalizer.js +35 -43
  161. package/utils/FileNormalizer.js.map +1 -1
  162. package/utils/FileUploadModifier.d.ts +9 -3
  163. package/utils/FileUploadModifier.js +36 -44
  164. package/utils/FileUploadModifier.js.map +1 -1
  165. package/utils/createFileNormalizerFromContext.d.ts +2 -2
  166. package/utils/createFileNormalizerFromContext.js +6 -12
  167. package/utils/createFileNormalizerFromContext.js.map +1 -1
  168. package/utils/getPresignedPostPayload.d.ts +4 -3
  169. package/utils/getPresignedPostPayload.js +38 -40
  170. package/utils/getPresignedPostPayload.js.map +1 -1
  171. package/utils/mimeTypes.js +6 -20
  172. package/utils/mimeTypes.js.map +1 -1
  173. package/utils/uploadFileToS3.d.ts +2 -5
  174. package/utils/uploadFileToS3.js +11 -23
  175. package/utils/uploadFileToS3.js.map +1 -1
  176. package/assetDelivery/createCustomAssetDelivery.d.ts +0 -12
  177. package/assetDelivery/createCustomAssetDelivery.js +0 -28
  178. package/assetDelivery/createCustomAssetDelivery.js.map +0 -1
  179. package/assetDelivery/customAssets/CustomAsset.d.ts +0 -6
  180. package/assetDelivery/customAssets/CustomAsset.js +0 -14
  181. package/assetDelivery/customAssets/CustomAsset.js.map +0 -1
  182. package/assetDelivery/customAssets/CustomAssetProcessor.d.ts +0 -10
  183. package/assetDelivery/customAssets/CustomAssetProcessor.js +0 -25
  184. package/assetDelivery/customAssets/CustomAssetProcessor.js.map +0 -1
  185. package/assetDelivery/customAssets/S3CustomAssetResolver.d.ts +0 -15
  186. package/assetDelivery/customAssets/S3CustomAssetResolver.js +0 -90
  187. package/assetDelivery/customAssets/S3CustomAssetResolver.js.map +0 -1
  188. package/assetDelivery/customAssets/customAssetDeliveryConfig.d.ts +0 -1
  189. package/assetDelivery/customAssets/customAssetDeliveryConfig.js +0 -30
  190. package/assetDelivery/customAssets/customAssetDeliveryConfig.js.map +0 -1
  191. package/assetDelivery/index.js.map +0 -1
  192. package/assetDelivery/s3/S3AssetMetadataReader.d.ts +0 -15
  193. package/assetDelivery/s3/S3AssetMetadataReader.js +0 -36
  194. package/assetDelivery/s3/S3AssetMetadataReader.js.map +0 -1
  195. package/assetDelivery/s3/transformation/legacyUtils.d.ts +0 -12
  196. package/assetDelivery/s3/transformation/legacyUtils.js +0 -34
  197. package/assetDelivery/s3/transformation/legacyUtils.js.map +0 -1
  198. package/assetDelivery/threatDetection/index.js.map +0 -1
  199. package/assetDelivery/threatDetection/types.js.map +0 -1
  200. package/assetDelivery/types.js.map +0 -1
  201. package/flushCdnCache/CdnPathsGenerator.d.ts +0 -4
  202. package/flushCdnCache/CdnPathsGenerator.js +0 -14
  203. package/flushCdnCache/CdnPathsGenerator.js.map +0 -1
  204. package/flushCdnCache/InvalidateCacheTask.d.ts +0 -18
  205. package/flushCdnCache/InvalidateCacheTask.js +0 -78
  206. package/flushCdnCache/InvalidateCacheTask.js.map +0 -1
  207. package/flushCdnCache/flushCacheOnFileDelete.d.ts +0 -3
  208. package/flushCdnCache/flushCacheOnFileDelete.js +0 -34
  209. package/flushCdnCache/flushCacheOnFileDelete.js.map +0 -1
  210. package/flushCdnCache/flushCacheOnFileUpdate.d.ts +0 -3
  211. package/flushCdnCache/flushCacheOnFileUpdate.js +0 -40
  212. package/flushCdnCache/flushCacheOnFileUpdate.js.map +0 -1
  213. package/flushCdnCache/index.d.ts +0 -1
  214. package/flushCdnCache/index.js +0 -15
  215. package/flushCdnCache/index.js.map +0 -1
  216. package/flushCdnCache/invalidateCacheTaskDefinition.d.ts +0 -2
  217. package/flushCdnCache/invalidateCacheTaskDefinition.js +0 -22
  218. package/flushCdnCache/invalidateCacheTaskDefinition.js.map +0 -1
  219. package/index.js.map +0 -1
  220. package/plugins/addFileMetadata.d.ts +0 -10
  221. package/plugins/addFileMetadata.js +0 -67
  222. package/plugins/addFileMetadata.js.map +0 -1
  223. package/plugins/checkPermissions.d.ts +0 -4
  224. package/plugins/checkPermissions.js +0 -44
  225. package/plugins/checkPermissions.js.map +0 -1
  226. package/plugins/fileStorageS3.d.ts +0 -3
  227. package/plugins/fileStorageS3.js +0 -60
  228. package/plugins/fileStorageS3.js.map +0 -1
  229. package/plugins/graphqlFileStorageS3.d.ts +0 -4
  230. package/plugins/graphqlFileStorageS3.js +0 -213
  231. package/plugins/graphqlFileStorageS3.js.map +0 -1
  232. package/types.js.map +0 -1
@@ -0,0 +1,233 @@
1
+ import p_map from "p-map";
2
+ import { staticSchemaKey } from "@webiny/api-graphql/graphql/staticSchemaKey.js";
3
+ import { CoreGraphQLSchemaFactory } from "@webiny/api-graphql/graphql/abstractions.js";
4
+ import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
5
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
6
+ import { S3 } from "@webiny/aws-sdk/client-s3/index.js";
7
+ import { ErrorResponse, Response } from "@webiny/api-graphql/responses.js";
8
+ import { GetSettingsUseCase } from "@webiny/api-file-manager/features/settings/GetSettings/abstractions.js";
9
+ import { getPresignedPostPayload } from "../utils/getPresignedPostPayload.js";
10
+ import { createFileNormalizerFromContext } from "../utils/createFileNormalizerFromContext.js";
11
+ import { checkPermissions } from "./checkPermissions.js";
12
+ import { CreateMultiPartUploadUseCase } from "../multiPartUpload/CreateMultiPartUploadUseCase.js";
13
+ import { CompleteMultiPartUploadUseCase } from "../multiPartUpload/CompleteMultiPartUploadUseCase.js";
14
+ const TYPE_DEFS = `
15
+ type UploadFileResponseDataFile {
16
+ id: ID!
17
+ name: String!
18
+ type: String!
19
+ size: Long!
20
+ key: String!
21
+ }
22
+
23
+ input PreSignedPostPayloadInput {
24
+ id: ID
25
+ name: String!
26
+ type: String!
27
+ size: Long!
28
+ key: String
29
+ keyPrefix: String
30
+ }
31
+
32
+ type GetPreSignedPostPayloadResponseDataFile {
33
+ id: ID!
34
+ name: String!
35
+ type: String!
36
+ size: Long!
37
+ key: String!
38
+ }
39
+
40
+ type GetPreSignedPostPayloadResponseData {
41
+ # Contains data that is necessary for initiating a file upload.
42
+ data: JSON!
43
+ file: UploadFileResponseDataFile!
44
+ }
45
+
46
+ type GetPreSignedPostPayloadResponse {
47
+ error: FmError
48
+ data: GetPreSignedPostPayloadResponseData
49
+ }
50
+
51
+ type MultiPartUploadFilePart {
52
+ partNumber: Int!
53
+ url: String!
54
+ }
55
+
56
+ type CreateMultiPartUploadResponseData {
57
+ file: GetPreSignedPostPayloadResponseDataFile!
58
+ uploadId: String!
59
+ parts: [MultiPartUploadFilePart!]!
60
+ }
61
+
62
+ type CompleteMultiPartUploadResponse {
63
+ data: Boolean
64
+ error: FmError
65
+ }
66
+
67
+ type GetPreSignedPostPayloadsResponse {
68
+ error: FmError
69
+ data: [GetPreSignedPostPayloadResponseData!]!
70
+ }
71
+
72
+ extend type FmQuery {
73
+ getPreSignedPostPayload(data: PreSignedPostPayloadInput!): GetPreSignedPostPayloadResponse
74
+ getPreSignedPostPayloads(
75
+ data: [PreSignedPostPayloadInput]!
76
+ ): GetPreSignedPostPayloadsResponse
77
+ }
78
+
79
+ type CreateMultiPartUploadResponse {
80
+ data: CreateMultiPartUploadResponseData
81
+ error: FmError
82
+ }
83
+
84
+ input MultiPartUploadFilePartInput {
85
+ partNumber: Int!
86
+ etag: String!
87
+ }
88
+
89
+ extend type FmMutation {
90
+ createMultiPartUpload(
91
+ data: PreSignedPostPayloadInput!
92
+ numberOfParts: Number!
93
+ ): CreateMultiPartUploadResponse
94
+
95
+ completeMultiPartUpload(
96
+ fileKey: String!
97
+ uploadId: String!
98
+ ): CompleteMultiPartUploadResponse
99
+ }
100
+ `;
101
+ class S3GraphQLSchemaImpl {
102
+ async execute(builder) {
103
+ builder.addTypeDefs(TYPE_DEFS);
104
+ builder.addResolver({
105
+ path: "FmQuery.getPreSignedPostPayload",
106
+ dependencies: [
107
+ IdentityContext,
108
+ GetSettingsUseCase,
109
+ TenantContext
110
+ ],
111
+ resolver (identityContext, getSettings, tenantContext) {
112
+ return async ({ args, context })=>{
113
+ try {
114
+ await checkPermissions(identityContext, {
115
+ rwd: "w"
116
+ });
117
+ const settingsResult = await getSettings.execute();
118
+ const settings = settingsResult.value;
119
+ const normalizer = createFileNormalizerFromContext(context);
120
+ const presignedPayload = await getPresignedPostPayload(await normalizer.normalizeFile(args.data), settings, tenantContext);
121
+ return new Response(presignedPayload);
122
+ } catch (e) {
123
+ return new ErrorResponse({
124
+ message: e.message,
125
+ code: e.code,
126
+ data: e.data
127
+ });
128
+ }
129
+ };
130
+ }
131
+ });
132
+ builder.addResolver({
133
+ path: "FmQuery.getPreSignedPostPayloads",
134
+ dependencies: [
135
+ IdentityContext,
136
+ GetSettingsUseCase,
137
+ TenantContext
138
+ ],
139
+ resolver (identityContext, getSettings, tenantContext) {
140
+ return async ({ args, context })=>{
141
+ await checkPermissions(identityContext, {
142
+ rwd: "w"
143
+ });
144
+ try {
145
+ const settingsResult = await getSettings.execute();
146
+ const settings = settingsResult.value;
147
+ const normalizer = createFileNormalizerFromContext(context);
148
+ const presignedPayloads = await p_map(args.data, async (data)=>getPresignedPostPayload(await normalizer.normalizeFile(data), settings, tenantContext));
149
+ return new Response(presignedPayloads);
150
+ } catch (e) {
151
+ return new ErrorResponse({
152
+ message: e.message,
153
+ code: e.code,
154
+ data: e.data
155
+ });
156
+ }
157
+ };
158
+ }
159
+ });
160
+ builder.addResolver({
161
+ path: "FmMutation.createMultiPartUpload",
162
+ dependencies: [
163
+ IdentityContext
164
+ ],
165
+ resolver (identityContext) {
166
+ return async ({ args, context })=>{
167
+ await checkPermissions(identityContext, {
168
+ rwd: "w"
169
+ });
170
+ const s3Client = new S3({
171
+ region: process.env.AWS_REGION
172
+ });
173
+ try {
174
+ const useCase = new CreateMultiPartUploadUseCase(String(process.env.S3_BUCKET), s3Client);
175
+ const normalizer = createFileNormalizerFromContext(context);
176
+ const multiPartUpload = await useCase.execute({
177
+ file: await normalizer.normalizeFile(args.data),
178
+ numberOfParts: args.numberOfParts
179
+ });
180
+ return new Response(multiPartUpload);
181
+ } catch (e) {
182
+ return new ErrorResponse({
183
+ message: e.message,
184
+ code: e.code,
185
+ data: e.data
186
+ });
187
+ }
188
+ };
189
+ }
190
+ });
191
+ builder.addResolver({
192
+ path: "FmMutation.completeMultiPartUpload",
193
+ dependencies: [
194
+ IdentityContext
195
+ ],
196
+ resolver (identityContext) {
197
+ return async ({ args })=>{
198
+ await checkPermissions(identityContext, {
199
+ rwd: "w"
200
+ });
201
+ const s3Client = new S3({
202
+ region: process.env.AWS_REGION
203
+ });
204
+ try {
205
+ const useCase = new CompleteMultiPartUploadUseCase(String(process.env.S3_BUCKET), s3Client);
206
+ await useCase.execute({
207
+ fileKey: args.fileKey,
208
+ uploadId: args.uploadId
209
+ });
210
+ return new Response(true);
211
+ } catch (e) {
212
+ return new ErrorResponse({
213
+ message: e.message,
214
+ code: e.code,
215
+ data: e.data
216
+ });
217
+ }
218
+ };
219
+ }
220
+ });
221
+ return builder;
222
+ }
223
+ constructor(){
224
+ this.getSchemaKey = staticSchemaKey("api-file-manager-s3/S3GraphQLSchemaImpl");
225
+ }
226
+ }
227
+ const S3GraphQLSchema = CoreGraphQLSchemaFactory.createImplementation({
228
+ implementation: S3GraphQLSchemaImpl,
229
+ dependencies: []
230
+ });
231
+ export { S3GraphQLSchema };
232
+
233
+ //# sourceMappingURL=S3GraphQLSchema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphql/S3GraphQLSchema.js","sources":["../../src/graphql/S3GraphQLSchema.ts"],"sourcesContent":["import pMap from \"p-map\";\nimport { staticSchemaKey } from \"@webiny/api-graphql/graphql/staticSchemaKey.js\";\nimport { CoreGraphQLSchemaFactory } from \"@webiny/api-graphql/graphql/abstractions.js\";\nimport { GraphQLSchemaBuilder } from \"@webiny/api-graphql/features/GraphQLSchemaBuilder/abstractions.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\nimport { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport { ErrorResponse, Response } from \"@webiny/api-graphql/responses.js\";\nimport { GetSettingsUseCase } from \"@webiny/api-file-manager/features/settings/GetSettings/abstractions.js\";\nimport { getPresignedPostPayload } from \"~/utils/getPresignedPostPayload.js\";\nimport { createFileNormalizerFromContext } from \"~/utils/createFileNormalizerFromContext.js\";\nimport { checkPermissions } from \"./checkPermissions.js\";\nimport type { PresignedPostPayloadData } from \"~/types.js\";\nimport { CreateMultiPartUploadUseCase } from \"~/multiPartUpload/CreateMultiPartUploadUseCase.js\";\nimport { CompleteMultiPartUploadUseCase } from \"~/multiPartUpload/CompleteMultiPartUploadUseCase.js\";\n\nconst TYPE_DEFS = /* GraphQL */ `\n type UploadFileResponseDataFile {\n id: ID!\n name: String!\n type: String!\n size: Long!\n key: String!\n }\n\n input PreSignedPostPayloadInput {\n id: ID\n name: String!\n type: String!\n size: Long!\n key: String\n keyPrefix: String\n }\n\n type GetPreSignedPostPayloadResponseDataFile {\n id: ID!\n name: String!\n type: String!\n size: Long!\n key: String!\n }\n\n type GetPreSignedPostPayloadResponseData {\n # Contains data that is necessary for initiating a file upload.\n data: JSON!\n file: UploadFileResponseDataFile!\n }\n\n type GetPreSignedPostPayloadResponse {\n error: FmError\n data: GetPreSignedPostPayloadResponseData\n }\n\n type MultiPartUploadFilePart {\n partNumber: Int!\n url: String!\n }\n\n type CreateMultiPartUploadResponseData {\n file: GetPreSignedPostPayloadResponseDataFile!\n uploadId: String!\n parts: [MultiPartUploadFilePart!]!\n }\n\n type CompleteMultiPartUploadResponse {\n data: Boolean\n error: FmError\n }\n\n type GetPreSignedPostPayloadsResponse {\n error: FmError\n data: [GetPreSignedPostPayloadResponseData!]!\n }\n\n extend type FmQuery {\n getPreSignedPostPayload(data: PreSignedPostPayloadInput!): GetPreSignedPostPayloadResponse\n getPreSignedPostPayloads(\n data: [PreSignedPostPayloadInput]!\n ): GetPreSignedPostPayloadsResponse\n }\n\n type CreateMultiPartUploadResponse {\n data: CreateMultiPartUploadResponseData\n error: FmError\n }\n\n input MultiPartUploadFilePartInput {\n partNumber: Int!\n etag: String!\n }\n\n extend type FmMutation {\n createMultiPartUpload(\n data: PreSignedPostPayloadInput!\n numberOfParts: Number!\n ): CreateMultiPartUploadResponse\n\n completeMultiPartUpload(\n fileKey: String!\n uploadId: String!\n ): CompleteMultiPartUploadResponse\n }\n`;\n\nclass S3GraphQLSchemaImpl implements CoreGraphQLSchemaFactory.Interface {\n public getSchemaKey = staticSchemaKey(\"api-file-manager-s3/S3GraphQLSchemaImpl\");\n\n public async execute(builder: GraphQLSchemaBuilder.Interface): CoreGraphQLSchemaFactory.Return {\n builder.addTypeDefs(TYPE_DEFS);\n\n builder.addResolver<{ data: PresignedPostPayloadData }>({\n path: \"FmQuery.getPreSignedPostPayload\",\n dependencies: [IdentityContext, GetSettingsUseCase, TenantContext],\n resolver(\n identityContext: IdentityContext.Interface,\n getSettings: GetSettingsUseCase.Interface,\n tenantContext: TenantContext.Interface\n ) {\n return async ({ args, context }) => {\n try {\n await checkPermissions(identityContext, { rwd: \"w\" });\n\n const settingsResult = await getSettings.execute();\n const settings = settingsResult.value;\n\n const normalizer = createFileNormalizerFromContext(context);\n const presignedPayload = await getPresignedPostPayload(\n await normalizer.normalizeFile(args.data),\n settings,\n tenantContext\n );\n\n return new Response(presignedPayload);\n } catch (e) {\n return new ErrorResponse({\n message: e.message,\n code: e.code,\n data: e.data\n });\n }\n };\n }\n });\n\n builder.addResolver<{ data: PresignedPostPayloadData[] }>({\n path: \"FmQuery.getPreSignedPostPayloads\",\n dependencies: [IdentityContext, GetSettingsUseCase, TenantContext],\n resolver(\n identityContext: IdentityContext.Interface,\n getSettings: GetSettingsUseCase.Interface,\n tenantContext: TenantContext.Interface\n ) {\n return async ({ args, context }) => {\n await checkPermissions(identityContext, { rwd: \"w\" });\n\n try {\n const settingsResult = await getSettings.execute();\n const settings = settingsResult.value;\n\n const normalizer = createFileNormalizerFromContext(context);\n\n const presignedPayloads = await pMap(args.data, async data => {\n return getPresignedPostPayload(\n await normalizer.normalizeFile(data),\n settings,\n tenantContext\n );\n });\n\n return new Response(presignedPayloads);\n } catch (e) {\n return new ErrorResponse({\n message: e.message,\n code: e.code,\n data: e.data\n });\n }\n };\n }\n });\n\n builder.addResolver<{ data: any; numberOfParts: number }>({\n path: \"FmMutation.createMultiPartUpload\",\n dependencies: [IdentityContext],\n resolver(identityContext: IdentityContext.Interface) {\n return async ({ args, context }) => {\n await checkPermissions(identityContext, { rwd: \"w\" });\n\n const s3Client = new S3({ region: process.env.AWS_REGION });\n\n try {\n const useCase = new CreateMultiPartUploadUseCase(\n String(process.env.S3_BUCKET),\n s3Client\n );\n\n const normalizer = createFileNormalizerFromContext(context);\n\n const multiPartUpload = await useCase.execute({\n file: await normalizer.normalizeFile(args.data),\n numberOfParts: args.numberOfParts\n });\n\n return new Response(multiPartUpload);\n } catch (e) {\n return new ErrorResponse({\n message: e.message,\n code: e.code,\n data: e.data\n });\n }\n };\n }\n });\n\n builder.addResolver<{ fileKey: string; uploadId: string }>({\n path: \"FmMutation.completeMultiPartUpload\",\n dependencies: [IdentityContext],\n resolver(identityContext: IdentityContext.Interface) {\n return async ({ args }) => {\n await checkPermissions(identityContext, { rwd: \"w\" });\n\n const s3Client = new S3({ region: process.env.AWS_REGION });\n\n try {\n const useCase = new CompleteMultiPartUploadUseCase(\n String(process.env.S3_BUCKET),\n s3Client\n );\n\n await useCase.execute({\n fileKey: args.fileKey,\n uploadId: args.uploadId\n });\n\n return new Response(true);\n } catch (e) {\n return new ErrorResponse({\n message: e.message,\n code: e.code,\n data: e.data\n });\n }\n };\n }\n });\n\n return builder;\n }\n}\n\nexport const S3GraphQLSchema = CoreGraphQLSchemaFactory.createImplementation({\n implementation: S3GraphQLSchemaImpl,\n dependencies: []\n});\n"],"names":["TYPE_DEFS","S3GraphQLSchemaImpl","builder","IdentityContext","GetSettingsUseCase","TenantContext","identityContext","getSettings","tenantContext","args","context","checkPermissions","settingsResult","settings","normalizer","createFileNormalizerFromContext","presignedPayload","getPresignedPostPayload","Response","e","ErrorResponse","presignedPayloads","pMap","data","s3Client","S3","process","useCase","CreateMultiPartUploadUseCase","String","multiPartUpload","CompleteMultiPartUploadUseCase","staticSchemaKey","S3GraphQLSchema","CoreGraphQLSchemaFactory"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { FilePermission } from "@webiny/api-file-manager/types.js";
2
+ import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
3
+ export declare const checkPermissions: (identityContext: IdentityContext.Interface, check?: {
4
+ rwd?: string;
5
+ }) => Promise<FilePermission[]>;
@@ -0,0 +1,22 @@
1
+ import { NotAuthorizedError } from "@webiny/api-core/features/security/shared/index.js";
2
+ const checkPermissions = async (identityContext, check = {})=>{
3
+ const filePermissions = await identityContext.getPermissions("fm.file");
4
+ const relevantFilePermissions = filePermissions.filter((current)=>{
5
+ if (check.rwd && !hasRwd(current, check.rwd)) return false;
6
+ return true;
7
+ });
8
+ if (0 === relevantFilePermissions.length) throw new NotAuthorizedError();
9
+ return relevantFilePermissions;
10
+ };
11
+ const hasRwd = (filesFilePermissions, rwd)=>{
12
+ if (!Array.isArray(filesFilePermissions)) filesFilePermissions = [
13
+ filesFilePermissions
14
+ ];
15
+ if (!rwd) return true;
16
+ const permissionWithoutRwdRestrictions = filesFilePermissions.some((permission)=>"string" != typeof permission.rwd);
17
+ if (permissionWithoutRwdRestrictions) return true;
18
+ return filesFilePermissions.some((permission)=>permission.rwd && permission.rwd.includes(rwd));
19
+ };
20
+ export { checkPermissions };
21
+
22
+ //# sourceMappingURL=checkPermissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphql/checkPermissions.js","sources":["../../src/graphql/checkPermissions.ts"],"sourcesContent":["import type { FilePermission } from \"@webiny/api-file-manager/types.js\";\nimport { NotAuthorizedError } from \"@webiny/api-core/features/security/shared/index.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\n\nexport const checkPermissions = async (\n identityContext: IdentityContext.Interface,\n check: { rwd?: string } = {}\n) => {\n const filePermissions = await identityContext.getPermissions<FilePermission>(\"fm.file\");\n\n const relevantFilePermissions = filePermissions.filter(current => {\n if (check.rwd && !hasRwd(current, check.rwd)) {\n return false;\n }\n\n return true;\n });\n\n if (relevantFilePermissions.length === 0) {\n throw new NotAuthorizedError();\n }\n\n return relevantFilePermissions;\n};\n\nconst hasRwd = (filesFilePermissions: FilePermission | FilePermission[], rwd: string): boolean => {\n if (!Array.isArray(filesFilePermissions)) {\n filesFilePermissions = [filesFilePermissions];\n }\n\n if (!rwd) {\n return true;\n }\n\n // Is there a permission that doesn't restrict RWD permissions, that means all RWD permissions are allowed.\n const permissionWithoutRwdRestrictions = filesFilePermissions.some(permission => {\n return typeof permission.rwd !== \"string\";\n });\n\n if (permissionWithoutRwdRestrictions) {\n return true;\n }\n\n // If there is no permission that doesn't restrict RWD permissions, that means we need to check if the RWD.\n return filesFilePermissions.some(permission => {\n return permission.rwd && permission.rwd.includes(rwd);\n });\n};\n"],"names":["checkPermissions","identityContext","check","filePermissions","relevantFilePermissions","current","hasRwd","NotAuthorizedError","filesFilePermissions","rwd","Array","permissionWithoutRwdRestrictions","permission"],"mappings":";AAIO,MAAMA,mBAAmB,OAC5BC,iBACAC,QAA0B,CAAC,CAAC;IAE5B,MAAMC,kBAAkB,MAAMF,gBAAgB,cAAc,CAAiB;IAE7E,MAAMG,0BAA0BD,gBAAgB,MAAM,CAACE,CAAAA;QACnD,IAAIH,MAAM,GAAG,IAAI,CAACI,OAAOD,SAASH,MAAM,GAAG,GACvC,OAAO;QAGX,OAAO;IACX;IAEA,IAAIE,AAAmC,MAAnCA,wBAAwB,MAAM,EAC9B,MAAM,IAAIG;IAGd,OAAOH;AACX;AAEA,MAAME,SAAS,CAACE,sBAAyDC;IACrE,IAAI,CAACC,MAAM,OAAO,CAACF,uBACfA,uBAAuB;QAACA;KAAqB;IAGjD,IAAI,CAACC,KACD,OAAO;IAIX,MAAME,mCAAmCH,qBAAqB,IAAI,CAACI,CAAAA,aACxD,AAA0B,YAA1B,OAAOA,WAAW,GAAG;IAGhC,IAAID,kCACA,OAAO;IAIX,OAAOH,qBAAqB,IAAI,CAACI,CAAAA,aACtBA,WAAW,GAAG,IAAIA,WAAW,GAAG,CAAC,QAAQ,CAACH;AAEzD"}
package/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- export { createFileUploadModifier } from "./utils/FileUploadModifier";
2
- export { createAssetDelivery } from "./assetDelivery/createAssetDelivery";
3
- export { createCustomAssetDelivery } from "./assetDelivery/createCustomAssetDelivery";
4
- declare const _default: () => (import("@webiny/handler-graphql/types").GraphQLSchemaPlugin<import("@webiny/api-file-manager/types").FileManagerContext> | import("@webiny/api").ContextPlugin<import("@webiny/api/types").Context> | (import("@webiny/api").ContextPlugin<import("@webiny/api-file-manager/types").FileManagerContext> | import("@webiny/tasks").TaskDefinitionPlugin<import("@webiny/api-file-manager/types").FileManagerContext, any, import("@webiny/tasks").ITaskResponseDoneResultOutput>)[])[];
5
- export default _default;
1
+ export { createFileUploadModifier } from "./utils/FileUploadModifier.js";
2
+ export { createAssetDelivery } from "./assetDelivery/createAssetDelivery.js";
3
+ export { FileManagerS3Feature } from "./FileManagerS3Feature.js";
4
+ export type { FileManagerS3FeatureConfig } from "./FileManagerS3Feature.js";
package/index.js CHANGED
@@ -1,36 +1,3 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- Object.defineProperty(exports, "createAssetDelivery", {
8
- enumerable: true,
9
- get: function () {
10
- return _createAssetDelivery.createAssetDelivery;
11
- }
12
- });
13
- Object.defineProperty(exports, "createCustomAssetDelivery", {
14
- enumerable: true,
15
- get: function () {
16
- return _createCustomAssetDelivery.createCustomAssetDelivery;
17
- }
18
- });
19
- Object.defineProperty(exports, "createFileUploadModifier", {
20
- enumerable: true,
21
- get: function () {
22
- return _FileUploadModifier.createFileUploadModifier;
23
- }
24
- });
25
- exports.default = void 0;
26
- var _graphqlFileStorageS = _interopRequireDefault(require("./plugins/graphqlFileStorageS3"));
27
- var _fileStorageS = _interopRequireDefault(require("./plugins/fileStorageS3"));
28
- var _addFileMetadata = require("./plugins/addFileMetadata");
29
- var _flushCdnCache = require("./flushCdnCache");
30
- var _FileUploadModifier = require("./utils/FileUploadModifier");
31
- var _createAssetDelivery = require("./assetDelivery/createAssetDelivery");
32
- var _createCustomAssetDelivery = require("./assetDelivery/createCustomAssetDelivery");
33
- var _default = () => [(0, _fileStorageS.default)(), _graphqlFileStorageS.default, (0, _addFileMetadata.addFileMetadata)(), (0, _flushCdnCache.flushCdnCache)()];
34
- exports.default = _default;
35
-
36
- //# sourceMappingURL=index.js.map
1
+ export { createFileUploadModifier } from "./utils/FileUploadModifier.js";
2
+ export { createAssetDelivery } from "./assetDelivery/createAssetDelivery.js";
3
+ export { FileManagerS3Feature } from "./FileManagerS3Feature.js";
@@ -1,4 +1,4 @@
1
- import type { S3 } from "@webiny/aws-sdk/client-s3";
1
+ import type { S3 } from "@webiny/aws-sdk/client-s3/index.js";
2
2
  interface CompleteMultiPartUploadParams {
3
3
  fileKey: string;
4
4
  uploadId: string;
@@ -1,65 +1,55 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.CompleteMultiPartUploadUseCase = void 0;
7
- var _clientS = require("@webiny/aws-sdk/client-s3");
1
+ import { CompleteMultipartUploadCommand, ListPartsCommand } from "@webiny/aws-sdk/client-s3/index.js";
8
2
  class CompleteMultiPartUploadUseCase {
9
- emptyMarkerValues = [undefined, "0"];
10
- constructor(bucket, s3Client) {
11
- this.bucket = bucket;
12
- this.s3 = s3Client;
13
- }
14
- async execute(params) {
15
- const uploadParams = {
16
- Bucket: this.bucket,
17
- Key: params.fileKey,
18
- UploadId: params.uploadId
19
- };
20
- const allParts = await this.getAllUploadParts(uploadParams);
21
- const s3Params = {
22
- ...uploadParams,
23
- MultipartUpload: {
24
- Parts: allParts
25
- }
26
- };
27
- try {
28
- const command = new _clientS.CompleteMultipartUploadCommand(s3Params);
29
- await this.s3.send(command);
30
- } catch (err) {
31
- console.error(err);
32
- throw err;
3
+ constructor(bucket, s3Client){
4
+ this.emptyMarkerValues = [
5
+ void 0,
6
+ "0"
7
+ ];
8
+ this.bucket = bucket;
9
+ this.s3 = s3Client;
10
+ }
11
+ async execute(params) {
12
+ const uploadParams = {
13
+ Bucket: this.bucket,
14
+ Key: params.fileKey,
15
+ UploadId: params.uploadId
16
+ };
17
+ const allParts = await this.getAllUploadParts(uploadParams);
18
+ const s3Params = {
19
+ ...uploadParams,
20
+ MultipartUpload: {
21
+ Parts: allParts
22
+ }
23
+ };
24
+ try {
25
+ const command = new CompleteMultipartUploadCommand(s3Params);
26
+ await this.s3.send(command);
27
+ } catch (err) {
28
+ console.error(err);
29
+ throw err;
30
+ }
31
+ }
32
+ async getAllUploadParts(params) {
33
+ const parts = [];
34
+ let marker;
35
+ while(true){
36
+ const { Parts, PartNumberMarker } = await this.s3.send(new ListPartsCommand({
37
+ ...params,
38
+ PartNumberMarker: marker
39
+ }));
40
+ if (Parts) Parts.forEach((part)=>parts.push(part));
41
+ marker = PartNumberMarker || void 0;
42
+ if (this.isMarkerEmpty(marker)) break;
43
+ }
44
+ return parts.map((part)=>({
45
+ ETag: part.ETag,
46
+ PartNumber: part.PartNumber
47
+ }));
33
48
  }
34
- }
35
- async getAllUploadParts(params) {
36
- const parts = [];
37
- let marker = undefined;
38
- while (true) {
39
- const {
40
- Parts,
41
- PartNumberMarker
42
- } = await this.s3.send(new _clientS.ListPartsCommand({
43
- ...params,
44
- PartNumberMarker: marker
45
- }));
46
- if (Parts) {
47
- Parts.forEach(part => parts.push(part));
48
- }
49
- marker = PartNumberMarker || undefined;
50
- if (this.isMarkerEmpty(marker)) {
51
- break;
52
- }
49
+ isMarkerEmpty(marker) {
50
+ return this.emptyMarkerValues.includes(marker);
53
51
  }
54
- return parts.map(part => ({
55
- ETag: part.ETag,
56
- PartNumber: part.PartNumber
57
- }));
58
- }
59
- isMarkerEmpty(marker) {
60
- return this.emptyMarkerValues.includes(marker);
61
- }
62
52
  }
63
- exports.CompleteMultiPartUploadUseCase = CompleteMultiPartUploadUseCase;
53
+ export { CompleteMultiPartUploadUseCase };
64
54
 
65
55
  //# sourceMappingURL=CompleteMultiPartUploadUseCase.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_clientS","require","CompleteMultiPartUploadUseCase","emptyMarkerValues","undefined","constructor","bucket","s3Client","s3","execute","params","uploadParams","Bucket","Key","fileKey","UploadId","uploadId","allParts","getAllUploadParts","s3Params","MultipartUpload","Parts","command","CompleteMultipartUploadCommand","send","err","console","error","parts","marker","PartNumberMarker","ListPartsCommand","forEach","part","push","isMarkerEmpty","map","ETag","PartNumber","includes","exports"],"sources":["CompleteMultiPartUploadUseCase.ts"],"sourcesContent":["import type { S3, Part, ListPartsOutput } from \"@webiny/aws-sdk/client-s3\";\nimport { ListPartsCommand, CompleteMultipartUploadCommand } from \"@webiny/aws-sdk/client-s3\";\n\ninterface CompleteMultiPartUploadParams {\n fileKey: string;\n uploadId: string;\n}\n\ninterface GetAllUploadPartsParams {\n Bucket: string;\n Key: string;\n UploadId: string;\n}\n\nexport class CompleteMultiPartUploadUseCase {\n private readonly s3: S3;\n private readonly bucket: string;\n private readonly emptyMarkerValues = [undefined, \"0\"];\n\n constructor(bucket: string, s3Client: S3) {\n this.bucket = bucket;\n this.s3 = s3Client;\n }\n\n async execute(params: CompleteMultiPartUploadParams) {\n const uploadParams = {\n Bucket: this.bucket,\n Key: params.fileKey,\n UploadId: params.uploadId\n };\n\n const allParts = await this.getAllUploadParts(uploadParams);\n\n const s3Params = {\n ...uploadParams,\n MultipartUpload: {\n Parts: allParts\n }\n };\n\n try {\n const command = new CompleteMultipartUploadCommand(s3Params);\n await this.s3.send(command);\n } catch (err) {\n console.error(err);\n throw err;\n }\n }\n\n private async getAllUploadParts(params: GetAllUploadPartsParams) {\n const parts: Part[] = [];\n\n let marker: string | undefined = undefined;\n while (true) {\n const { Parts, PartNumberMarker }: ListPartsOutput = await this.s3.send(\n new ListPartsCommand({\n ...params,\n PartNumberMarker: marker\n })\n );\n\n if (Parts) {\n Parts.forEach(part => parts.push(part));\n }\n\n marker = PartNumberMarker || undefined;\n if (this.isMarkerEmpty(marker)) {\n break;\n }\n }\n\n return parts.map(part => ({\n ETag: part.ETag as string,\n PartNumber: part.PartNumber as number\n }));\n }\n\n private isMarkerEmpty(marker: string | undefined) {\n return this.emptyMarkerValues.includes(marker);\n }\n}\n"],"mappings":";;;;;;AACA,IAAAA,QAAA,GAAAC,OAAA;AAaO,MAAMC,8BAA8B,CAAC;EAGvBC,iBAAiB,GAAG,CAACC,SAAS,EAAE,GAAG,CAAC;EAErDC,WAAWA,CAACC,MAAc,EAAEC,QAAY,EAAE;IACtC,IAAI,CAACD,MAAM,GAAGA,MAAM;IACpB,IAAI,CAACE,EAAE,GAAGD,QAAQ;EACtB;EAEA,MAAME,OAAOA,CAACC,MAAqC,EAAE;IACjD,MAAMC,YAAY,GAAG;MACjBC,MAAM,EAAE,IAAI,CAACN,MAAM;MACnBO,GAAG,EAAEH,MAAM,CAACI,OAAO;MACnBC,QAAQ,EAAEL,MAAM,CAACM;IACrB,CAAC;IAED,MAAMC,QAAQ,GAAG,MAAM,IAAI,CAACC,iBAAiB,CAACP,YAAY,CAAC;IAE3D,MAAMQ,QAAQ,GAAG;MACb,GAAGR,YAAY;MACfS,eAAe,EAAE;QACbC,KAAK,EAAEJ;MACX;IACJ,CAAC;IAED,IAAI;MACA,MAAMK,OAAO,GAAG,IAAIC,uCAA8B,CAACJ,QAAQ,CAAC;MAC5D,MAAM,IAAI,CAACX,EAAE,CAACgB,IAAI,CAACF,OAAO,CAAC;IAC/B,CAAC,CAAC,OAAOG,GAAG,EAAE;MACVC,OAAO,CAACC,KAAK,CAACF,GAAG,CAAC;MAClB,MAAMA,GAAG;IACb;EACJ;EAEA,MAAcP,iBAAiBA,CAACR,MAA+B,EAAE;IAC7D,MAAMkB,KAAa,GAAG,EAAE;IAExB,IAAIC,MAA0B,GAAGzB,SAAS;IAC1C,OAAO,IAAI,EAAE;MACT,MAAM;QAAEiB,KAAK;QAAES;MAAkC,CAAC,GAAG,MAAM,IAAI,CAACtB,EAAE,CAACgB,IAAI,CACnE,IAAIO,yBAAgB,CAAC;QACjB,GAAGrB,MAAM;QACToB,gBAAgB,EAAED;MACtB,CAAC,CACL,CAAC;MAED,IAAIR,KAAK,EAAE;QACPA,KAAK,CAACW,OAAO,CAACC,IAAI,IAAIL,KAAK,CAACM,IAAI,CAACD,IAAI,CAAC,CAAC;MAC3C;MAEAJ,MAAM,GAAGC,gBAAgB,IAAI1B,SAAS;MACtC,IAAI,IAAI,CAAC+B,aAAa,CAACN,MAAM,CAAC,EAAE;QAC5B;MACJ;IACJ;IAEA,OAAOD,KAAK,CAACQ,GAAG,CAACH,IAAI,KAAK;MACtBI,IAAI,EAAEJ,IAAI,CAACI,IAAc;MACzBC,UAAU,EAAEL,IAAI,CAACK;IACrB,CAAC,CAAC,CAAC;EACP;EAEQH,aAAaA,CAACN,MAA0B,EAAE;IAC9C,OAAO,IAAI,CAAC1B,iBAAiB,CAACoC,QAAQ,CAACV,MAAM,CAAC;EAClD;AACJ;AAACW,OAAA,CAAAtC,8BAAA,GAAAA,8BAAA","ignoreList":[]}
1
+ {"version":3,"file":"multiPartUpload/CompleteMultiPartUploadUseCase.js","sources":["../../src/multiPartUpload/CompleteMultiPartUploadUseCase.ts"],"sourcesContent":["import type { S3, Part, ListPartsOutput } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport {\n ListPartsCommand,\n CompleteMultipartUploadCommand\n} from \"@webiny/aws-sdk/client-s3/index.js\";\n\ninterface CompleteMultiPartUploadParams {\n fileKey: string;\n uploadId: string;\n}\n\ninterface GetAllUploadPartsParams {\n Bucket: string;\n Key: string;\n UploadId: string;\n}\n\nexport class CompleteMultiPartUploadUseCase {\n private readonly s3: S3;\n private readonly bucket: string;\n private readonly emptyMarkerValues = [undefined, \"0\"];\n\n constructor(bucket: string, s3Client: S3) {\n this.bucket = bucket;\n this.s3 = s3Client;\n }\n\n async execute(params: CompleteMultiPartUploadParams) {\n const uploadParams = {\n Bucket: this.bucket,\n Key: params.fileKey,\n UploadId: params.uploadId\n };\n\n const allParts = await this.getAllUploadParts(uploadParams);\n\n const s3Params = {\n ...uploadParams,\n MultipartUpload: {\n Parts: allParts\n }\n };\n\n try {\n const command = new CompleteMultipartUploadCommand(s3Params);\n await this.s3.send(command);\n } catch (err) {\n console.error(err);\n throw err;\n }\n }\n\n private async getAllUploadParts(params: GetAllUploadPartsParams) {\n const parts: Part[] = [];\n\n let marker: string | undefined = undefined;\n while (true) {\n const { Parts, PartNumberMarker }: ListPartsOutput = await this.s3.send(\n new ListPartsCommand({\n ...params,\n PartNumberMarker: marker\n })\n );\n\n if (Parts) {\n Parts.forEach(part => parts.push(part));\n }\n\n marker = PartNumberMarker || undefined;\n if (this.isMarkerEmpty(marker)) {\n break;\n }\n }\n\n return parts.map(part => ({\n ETag: part.ETag as string,\n PartNumber: part.PartNumber as number\n }));\n }\n\n private isMarkerEmpty(marker: string | undefined) {\n return this.emptyMarkerValues.includes(marker);\n }\n}\n"],"names":["CompleteMultiPartUploadUseCase","bucket","s3Client","undefined","params","uploadParams","allParts","s3Params","command","CompleteMultipartUploadCommand","err","console","parts","marker","Parts","PartNumberMarker","ListPartsCommand","part"],"mappings":";AAiBO,MAAMA;IAKT,YAAYC,MAAc,EAAEC,QAAY,CAAE;aAFzB,iBAAiB,GAAG;YAACC;YAAW;SAAI;QAGjD,IAAI,CAAC,MAAM,GAAGF;QACd,IAAI,CAAC,EAAE,GAAGC;IACd;IAEA,MAAM,QAAQE,MAAqC,EAAE;QACjD,MAAMC,eAAe;YACjB,QAAQ,IAAI,CAAC,MAAM;YACnB,KAAKD,OAAO,OAAO;YACnB,UAAUA,OAAO,QAAQ;QAC7B;QAEA,MAAME,WAAW,MAAM,IAAI,CAAC,iBAAiB,CAACD;QAE9C,MAAME,WAAW;YACb,GAAGF,YAAY;YACf,iBAAiB;gBACb,OAAOC;YACX;QACJ;QAEA,IAAI;YACA,MAAME,UAAU,IAAIC,+BAA+BF;YACnD,MAAM,IAAI,CAAC,EAAE,CAAC,IAAI,CAACC;QACvB,EAAE,OAAOE,KAAK;YACVC,QAAQ,KAAK,CAACD;YACd,MAAMA;QACV;IACJ;IAEA,MAAc,kBAAkBN,MAA+B,EAAE;QAC7D,MAAMQ,QAAgB,EAAE;QAExB,IAAIC;QACJ,MAAO,KAAM;YACT,MAAM,EAAEC,KAAK,EAAEC,gBAAgB,EAAE,GAAoB,MAAM,IAAI,CAAC,EAAE,CAAC,IAAI,CACnE,IAAIC,iBAAiB;gBACjB,GAAGZ,MAAM;gBACT,kBAAkBS;YACtB;YAGJ,IAAIC,OACAA,MAAM,OAAO,CAACG,CAAAA,OAAQL,MAAM,IAAI,CAACK;YAGrCJ,SAASE,oBAAoBZ;YAC7B,IAAI,IAAI,CAAC,aAAa,CAACU,SACnB;QAER;QAEA,OAAOD,MAAM,GAAG,CAACK,CAAAA,OAAS;gBACtB,MAAMA,KAAK,IAAI;gBACf,YAAYA,KAAK,UAAU;YAC/B;IACJ;IAEQ,cAAcJ,MAA0B,EAAE;QAC9C,OAAO,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAACA;IAC3C;AACJ"}
@@ -1,5 +1,5 @@
1
- import type { S3 } from "@webiny/aws-sdk/client-s3";
2
- import type { FileData } from "../types";
1
+ import type { S3 } from "@webiny/aws-sdk/client-s3/index.js";
2
+ import type { FileData } from "../types.js";
3
3
  interface CreateMultiPartUploadParams {
4
4
  file: FileData;
5
5
  numberOfParts: number;
@@ -1,48 +1,34 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.CreateMultiPartUploadUseCase = void 0;
7
- var _clientS = require("@webiny/aws-sdk/client-s3");
1
+ import { UploadPartCommand, getSignedUrl } from "@webiny/aws-sdk/client-s3/index.js";
8
2
  class CreateMultiPartUploadUseCase {
9
- constructor(bucket, s3Client) {
10
- this.bucket = bucket;
11
- this.s3 = s3Client;
12
- }
13
- async execute({
14
- file,
15
- numberOfParts
16
- }) {
17
- const s3Params = {
18
- Bucket: this.bucket,
19
- Key: file.key
20
- };
21
- const {
22
- UploadId
23
- } = await this.s3.createMultipartUpload(s3Params);
24
- const parts = await Promise.all(Array.from({
25
- length: numberOfParts
26
- }).map((_, index) => {
27
- return (0, _clientS.getSignedUrl)(this.s3, new _clientS.UploadPartCommand({
28
- ...s3Params,
29
- UploadId,
30
- PartNumber: index + 1
31
- }), {
32
- // URL expires after 24 hours.
33
- expiresIn: 86400
34
- }).then(url => ({
35
- url,
36
- partNumber: index + 1
37
- }));
38
- }));
39
- return {
40
- file,
41
- uploadId: UploadId,
42
- parts
43
- };
44
- }
3
+ constructor(bucket, s3Client){
4
+ this.bucket = bucket;
5
+ this.s3 = s3Client;
6
+ }
7
+ async execute({ file, numberOfParts }) {
8
+ const s3Params = {
9
+ Bucket: this.bucket,
10
+ Key: file.key
11
+ };
12
+ const { UploadId } = await this.s3.createMultipartUpload(s3Params);
13
+ const parts = await Promise.all(Array.from({
14
+ length: numberOfParts
15
+ }).map((_, index)=>getSignedUrl(this.s3, new UploadPartCommand({
16
+ ...s3Params,
17
+ UploadId,
18
+ PartNumber: index + 1
19
+ }), {
20
+ expiresIn: 86400
21
+ }).then((url)=>({
22
+ url,
23
+ partNumber: index + 1
24
+ }))));
25
+ return {
26
+ file,
27
+ uploadId: UploadId,
28
+ parts
29
+ };
30
+ }
45
31
  }
46
- exports.CreateMultiPartUploadUseCase = CreateMultiPartUploadUseCase;
32
+ export { CreateMultiPartUploadUseCase };
47
33
 
48
34
  //# sourceMappingURL=CreateMultiPartUploadUseCase.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_clientS","require","CreateMultiPartUploadUseCase","constructor","bucket","s3Client","s3","execute","file","numberOfParts","s3Params","Bucket","Key","key","UploadId","createMultipartUpload","parts","Promise","all","Array","from","length","map","_","index","getSignedUrl","UploadPartCommand","PartNumber","expiresIn","then","url","partNumber","uploadId","exports"],"sources":["CreateMultiPartUploadUseCase.ts"],"sourcesContent":["import type { S3 } from \"@webiny/aws-sdk/client-s3\";\nimport { getSignedUrl, UploadPartCommand } from \"@webiny/aws-sdk/client-s3\";\nimport type { FileData } from \"~/types\";\n\ninterface CreateMultiPartUploadParams {\n file: FileData;\n numberOfParts: number;\n}\n\nexport class CreateMultiPartUploadUseCase {\n private readonly s3: S3;\n private readonly bucket: string;\n\n constructor(bucket: string, s3Client: S3) {\n this.bucket = bucket;\n this.s3 = s3Client;\n }\n\n async execute({ file, numberOfParts }: CreateMultiPartUploadParams) {\n const s3Params = { Bucket: this.bucket, Key: file.key };\n\n const { UploadId } = await this.s3.createMultipartUpload(s3Params);\n\n const parts = await Promise.all(\n Array.from({ length: numberOfParts }).map((_, index) => {\n return getSignedUrl(\n this.s3,\n new UploadPartCommand({ ...s3Params, UploadId, PartNumber: index + 1 }),\n {\n // URL expires after 24 hours.\n expiresIn: 86400\n }\n ).then(url => ({\n url,\n partNumber: index + 1\n }));\n })\n );\n\n return {\n file,\n uploadId: UploadId,\n parts\n };\n }\n}\n"],"mappings":";;;;;;AACA,IAAAA,QAAA,GAAAC,OAAA;AAQO,MAAMC,4BAA4B,CAAC;EAItCC,WAAWA,CAACC,MAAc,EAAEC,QAAY,EAAE;IACtC,IAAI,CAACD,MAAM,GAAGA,MAAM;IACpB,IAAI,CAACE,EAAE,GAAGD,QAAQ;EACtB;EAEA,MAAME,OAAOA,CAAC;IAAEC,IAAI;IAAEC;EAA2C,CAAC,EAAE;IAChE,MAAMC,QAAQ,GAAG;MAAEC,MAAM,EAAE,IAAI,CAACP,MAAM;MAAEQ,GAAG,EAAEJ,IAAI,CAACK;IAAI,CAAC;IAEvD,MAAM;MAAEC;IAAS,CAAC,GAAG,MAAM,IAAI,CAACR,EAAE,CAACS,qBAAqB,CAACL,QAAQ,CAAC;IAElE,MAAMM,KAAK,GAAG,MAAMC,OAAO,CAACC,GAAG,CAC3BC,KAAK,CAACC,IAAI,CAAC;MAAEC,MAAM,EAAEZ;IAAc,CAAC,CAAC,CAACa,GAAG,CAAC,CAACC,CAAC,EAAEC,KAAK,KAAK;MACpD,OAAO,IAAAC,qBAAY,EACf,IAAI,CAACnB,EAAE,EACP,IAAIoB,0BAAiB,CAAC;QAAE,GAAGhB,QAAQ;QAAEI,QAAQ;QAAEa,UAAU,EAAEH,KAAK,GAAG;MAAE,CAAC,CAAC,EACvE;QACI;QACAI,SAAS,EAAE;MACf,CACJ,CAAC,CAACC,IAAI,CAACC,GAAG,KAAK;QACXA,GAAG;QACHC,UAAU,EAAEP,KAAK,GAAG;MACxB,CAAC,CAAC,CAAC;IACP,CAAC,CACL,CAAC;IAED,OAAO;MACHhB,IAAI;MACJwB,QAAQ,EAAElB,QAAQ;MAClBE;IACJ,CAAC;EACL;AACJ;AAACiB,OAAA,CAAA/B,4BAAA,GAAAA,4BAAA","ignoreList":[]}
1
+ {"version":3,"file":"multiPartUpload/CreateMultiPartUploadUseCase.js","sources":["../../src/multiPartUpload/CreateMultiPartUploadUseCase.ts"],"sourcesContent":["import type { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport { getSignedUrl, UploadPartCommand } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport type { FileData } from \"~/types.js\";\n\ninterface CreateMultiPartUploadParams {\n file: FileData;\n numberOfParts: number;\n}\n\nexport class CreateMultiPartUploadUseCase {\n private readonly s3: S3;\n private readonly bucket: string;\n\n constructor(bucket: string, s3Client: S3) {\n this.bucket = bucket;\n this.s3 = s3Client;\n }\n\n async execute({ file, numberOfParts }: CreateMultiPartUploadParams) {\n const s3Params = { Bucket: this.bucket, Key: file.key };\n\n const { UploadId } = await this.s3.createMultipartUpload(s3Params);\n\n const parts = await Promise.all(\n Array.from({ length: numberOfParts }).map((_, index) => {\n return getSignedUrl(\n this.s3,\n new UploadPartCommand({ ...s3Params, UploadId, PartNumber: index + 1 }),\n {\n // URL expires after 24 hours.\n expiresIn: 86400\n }\n ).then(url => ({\n url,\n partNumber: index + 1\n }));\n })\n );\n\n return {\n file,\n uploadId: UploadId,\n parts\n };\n }\n}\n"],"names":["CreateMultiPartUploadUseCase","bucket","s3Client","file","numberOfParts","s3Params","UploadId","parts","Promise","Array","_","index","getSignedUrl","UploadPartCommand","url"],"mappings":";AASO,MAAMA;IAIT,YAAYC,MAAc,EAAEC,QAAY,CAAE;QACtC,IAAI,CAAC,MAAM,GAAGD;QACd,IAAI,CAAC,EAAE,GAAGC;IACd;IAEA,MAAM,QAAQ,EAAEC,IAAI,EAAEC,aAAa,EAA+B,EAAE;QAChE,MAAMC,WAAW;YAAE,QAAQ,IAAI,CAAC,MAAM;YAAE,KAAKF,KAAK,GAAG;QAAC;QAEtD,MAAM,EAAEG,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAACD;QAEzD,MAAME,QAAQ,MAAMC,QAAQ,GAAG,CAC3BC,MAAM,IAAI,CAAC;YAAE,QAAQL;QAAc,GAAG,GAAG,CAAC,CAACM,GAAGC,QACnCC,aACH,IAAI,CAAC,EAAE,EACP,IAAIC,kBAAkB;gBAAE,GAAGR,QAAQ;gBAAEC;gBAAU,YAAYK,QAAQ;YAAE,IACrE;gBAEI,WAAW;YACf,GACF,IAAI,CAACG,CAAAA,MAAQ;oBACXA;oBACA,YAAYH,QAAQ;gBACxB;QAIR,OAAO;YACHR;YACA,UAAUG;YACVC;QACJ;IACJ;AACJ"}