@maas/payload-plugin-media-cloud 0.0.30 → 0.0.32

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 (157) hide show
  1. package/dist/adapter/handleDelete.d.mts +3 -3
  2. package/dist/adapter/handleDelete.mjs +6 -6
  3. package/dist/adapter/handleDelete.mjs.map +1 -1
  4. package/dist/adapter/staticHandler.d.mts +5 -3
  5. package/dist/adapter/staticHandler.mjs +8 -7
  6. package/dist/adapter/staticHandler.mjs.map +1 -1
  7. package/dist/adapter/storageAdapter.d.mts +3 -3
  8. package/dist/adapter/storageAdapter.mjs +4 -4
  9. package/dist/adapter/storageAdapter.mjs.map +1 -1
  10. package/dist/collectionHooks/afterChange.d.mts +7 -0
  11. package/dist/collectionHooks/afterChange.mjs +39 -0
  12. package/dist/collectionHooks/afterChange.mjs.map +1 -0
  13. package/dist/collectionHooks/beforeChange.d.mts +7 -0
  14. package/dist/collectionHooks/beforeChange.mjs +33 -0
  15. package/dist/collectionHooks/beforeChange.mjs.map +1 -0
  16. package/dist/collections/mediaCollection.d.mts +3 -2
  17. package/dist/collections/mediaCollection.mjs +46 -198
  18. package/dist/collections/mediaCollection.mjs.map +1 -1
  19. package/dist/components/folderFileCard/folderFileCard.d.mts +13 -0
  20. package/dist/components/folderFileCard/folderFileCard.mjs +30 -0
  21. package/dist/components/folderFileCard/folderFileCard.mjs.map +1 -0
  22. package/dist/components/gridContext/gridContext.d.mts +51 -0
  23. package/dist/components/gridContext/gridContext.mjs +227 -0
  24. package/dist/components/gridContext/gridContext.mjs.map +1 -0
  25. package/dist/components/gridView/gridView.css +50 -0
  26. package/dist/components/gridView/gridView.d.mts +16 -0
  27. package/dist/components/gridView/gridView.mjs +124 -0
  28. package/dist/components/gridView/gridView.mjs.map +1 -0
  29. package/dist/components/gridView/index.d.mts +2 -0
  30. package/dist/components/gridView/index.mjs +3 -0
  31. package/dist/components/index.d.mts +9 -7
  32. package/dist/components/index.mjs +5 -4
  33. package/dist/components/itemCardGrid/itemCardGrid.css +12 -0
  34. package/dist/components/itemCardGrid/itemCardGrid.d.mts +18 -0
  35. package/dist/components/itemCardGrid/itemCardGrid.mjs +22 -0
  36. package/dist/components/itemCardGrid/itemCardGrid.mjs.map +1 -0
  37. package/dist/components/muxPreview/index.d.mts +2 -0
  38. package/dist/components/muxPreview/index.mjs +3 -0
  39. package/dist/components/{mux-preview/mux-preview.d.mts → muxPreview/muxPreview.d.mts} +2 -2
  40. package/dist/components/{mux-preview/mux-preview.mjs → muxPreview/muxPreview.mjs} +2 -2
  41. package/dist/components/muxPreview/muxPreview.mjs.map +1 -0
  42. package/dist/components/uploadHandler/index.d.mts +2 -0
  43. package/dist/components/uploadHandler/index.mjs +3 -0
  44. package/dist/components/uploadHandler/uploadHandler.d.mts +20 -0
  45. package/dist/components/{upload-handler/upload-handler.mjs → uploadHandler/uploadHandler.mjs} +82 -52
  46. package/dist/components/uploadHandler/uploadHandler.mjs.map +1 -0
  47. package/dist/components/uploadManager/index.d.mts +2 -0
  48. package/dist/components/uploadManager/index.mjs +3 -0
  49. package/dist/components/{upload-manager/upload-manager.d.mts → uploadManager/uploadManager.d.mts} +3 -3
  50. package/dist/components/{upload-manager/upload-manager.mjs → uploadManager/uploadManager.mjs} +3 -3
  51. package/dist/components/uploadManager/uploadManager.mjs.map +1 -0
  52. package/dist/endpoints/fileExistsHandler.d.mts +12 -0
  53. package/dist/endpoints/{tusFileExistsHandler.mjs → fileExistsHandler.mjs} +7 -7
  54. package/dist/endpoints/fileExistsHandler.mjs.map +1 -0
  55. package/dist/endpoints/muxAssetHandler.d.mts +1 -0
  56. package/dist/endpoints/muxAssetHandler.mjs +3 -3
  57. package/dist/endpoints/muxAssetHandler.mjs.map +1 -1
  58. package/dist/endpoints/muxWebhookHandler.d.mts +1 -0
  59. package/dist/endpoints/muxWebhookHandler.mjs +6 -5
  60. package/dist/endpoints/muxWebhookHandler.mjs.map +1 -1
  61. package/dist/endpoints/tusCleanupHandler.d.mts +3 -2
  62. package/dist/endpoints/tusCleanupHandler.mjs +4 -4
  63. package/dist/endpoints/tusCleanupHandler.mjs.map +1 -1
  64. package/dist/endpoints/tusFolderHandler.d.mts +12 -0
  65. package/dist/endpoints/tusFolderHandler.mjs +39 -0
  66. package/dist/endpoints/tusFolderHandler.mjs.map +1 -0
  67. package/dist/endpoints/tusPostProcessorHandler.d.mts +3 -2
  68. package/dist/endpoints/tusPostProcessorHandler.mjs +6 -5
  69. package/dist/endpoints/tusPostProcessorHandler.mjs.map +1 -1
  70. package/dist/fields/alt.d.mts +7 -0
  71. package/dist/fields/alt.mjs +10 -0
  72. package/dist/fields/alt.mjs.map +1 -0
  73. package/dist/fields/filename.d.mts +7 -0
  74. package/dist/fields/filename.mjs +14 -0
  75. package/dist/fields/filename.mjs.map +1 -0
  76. package/dist/fields/height.d.mts +7 -0
  77. package/dist/fields/height.mjs +15 -0
  78. package/dist/fields/height.mjs.map +1 -0
  79. package/dist/fields/mux.d.mts +7 -0
  80. package/dist/fields/mux.mjs +149 -0
  81. package/dist/fields/mux.mjs.map +1 -0
  82. package/dist/fields/path.d.mts +7 -0
  83. package/dist/fields/path.mjs +14 -0
  84. package/dist/fields/path.mjs.map +1 -0
  85. package/dist/fields/storage.d.mts +7 -0
  86. package/dist/fields/storage.mjs +18 -0
  87. package/dist/fields/storage.mjs.map +1 -0
  88. package/dist/fields/thumbnail.d.mts +7 -0
  89. package/dist/fields/thumbnail.mjs +17 -0
  90. package/dist/fields/thumbnail.mjs.map +1 -0
  91. package/dist/fields/width.d.mts +7 -0
  92. package/dist/fields/width.mjs +15 -0
  93. package/dist/fields/width.mjs.map +1 -0
  94. package/dist/hooks/useErrorHandler.d.mts +1 -1
  95. package/dist/hooks/useErrorHandler.mjs +4 -2
  96. package/dist/hooks/useErrorHandler.mjs.map +1 -1
  97. package/dist/plugin.d.mts +5 -4
  98. package/dist/plugin.mjs +53 -29
  99. package/dist/plugin.mjs.map +1 -1
  100. package/dist/tus/stores/s3/{expiration-manager.d.mts → expirationManager.d.mts} +4 -3
  101. package/dist/tus/stores/s3/{expiration-manager.mjs → expirationManager.mjs} +6 -3
  102. package/dist/tus/stores/s3/expirationManager.mjs.map +1 -0
  103. package/dist/tus/stores/s3/{file-operations.d.mts → fileOperations.d.mts} +2 -2
  104. package/dist/tus/stores/s3/{file-operations.mjs → fileOperations.mjs} +2 -2
  105. package/dist/tus/stores/s3/fileOperations.mjs.map +1 -0
  106. package/dist/tus/stores/s3/index.d.mts +1 -1
  107. package/dist/tus/stores/s3/index.mjs +20 -9
  108. package/dist/tus/stores/s3/index.mjs.map +1 -1
  109. package/dist/tus/stores/s3/{metadata-manager.d.mts → metadataManager.d.mts} +4 -2
  110. package/dist/tus/stores/s3/{metadata-manager.mjs → metadataManager.mjs} +6 -5
  111. package/dist/tus/stores/s3/metadataManager.mjs.map +1 -0
  112. package/dist/tus/stores/s3/{parts-manager.d.mts → partsManager.d.mts} +4 -4
  113. package/dist/tus/stores/s3/{parts-manager.mjs → partsManager.mjs} +67 -29
  114. package/dist/tus/stores/s3/partsManager.mjs.map +1 -0
  115. package/dist/tus/stores/s3/{s3-store.d.mts → s3Store.d.mts} +38 -32
  116. package/dist/tus/stores/s3/{s3-store.mjs → s3Store.mjs} +102 -57
  117. package/dist/tus/stores/s3/s3Store.mjs.map +1 -0
  118. package/dist/types/errors.d.mts +32 -0
  119. package/dist/types/errors.mjs +32 -0
  120. package/dist/types/errors.mjs.map +1 -1
  121. package/dist/types/index.d.mts +42 -4
  122. package/dist/utils/buildS3Path.d.mts +10 -0
  123. package/dist/utils/buildS3Path.mjs +16 -0
  124. package/dist/utils/buildS3Path.mjs.map +1 -0
  125. package/dist/utils/buildThumbnailURL.d.mts +14 -0
  126. package/dist/utils/buildThumbnailURL.mjs +10 -0
  127. package/dist/utils/buildThumbnailURL.mjs.map +1 -0
  128. package/dist/utils/defaultOptions.d.mts +7 -0
  129. package/dist/utils/defaultOptions.mjs +12 -0
  130. package/dist/utils/defaultOptions.mjs.map +1 -0
  131. package/dist/utils/file.d.mts +16 -2
  132. package/dist/utils/file.mjs +58 -6
  133. package/dist/utils/file.mjs.map +1 -1
  134. package/dist/utils/mux.mjs +19 -8
  135. package/dist/utils/mux.mjs.map +1 -1
  136. package/dist/utils/tus.d.mts +9 -6
  137. package/dist/utils/tus.mjs +31 -11
  138. package/dist/utils/tus.mjs.map +1 -1
  139. package/package.json +9 -4
  140. package/dist/components/mux-preview/index.d.mts +0 -2
  141. package/dist/components/mux-preview/index.mjs +0 -3
  142. package/dist/components/mux-preview/mux-preview.mjs.map +0 -1
  143. package/dist/components/upload-handler/index.d.mts +0 -2
  144. package/dist/components/upload-handler/index.mjs +0 -3
  145. package/dist/components/upload-handler/upload-handler.d.mts +0 -22
  146. package/dist/components/upload-handler/upload-handler.mjs.map +0 -1
  147. package/dist/components/upload-manager/index.d.mts +0 -2
  148. package/dist/components/upload-manager/index.mjs +0 -3
  149. package/dist/components/upload-manager/upload-manager.mjs.map +0 -1
  150. package/dist/endpoints/tusFileExistsHandler.d.mts +0 -11
  151. package/dist/endpoints/tusFileExistsHandler.mjs.map +0 -1
  152. package/dist/tus/stores/s3/expiration-manager.mjs.map +0 -1
  153. package/dist/tus/stores/s3/file-operations.mjs.map +0 -1
  154. package/dist/tus/stores/s3/metadata-manager.mjs.map +0 -1
  155. package/dist/tus/stores/s3/parts-manager.mjs.map +0 -1
  156. package/dist/tus/stores/s3/s3-store.mjs.map +0 -1
  157. /package/dist/components/{upload-manager/upload-manager.css → uploadManager/uploadManager.css} +0 -0
@@ -0,0 +1,7 @@
1
+ import { TextField } from "payload";
2
+
3
+ //#region src/fields/thumbnail.d.ts
4
+ declare const thumbnailField: TextField;
5
+ //#endregion
6
+ export { thumbnailField };
7
+ //# sourceMappingURL=thumbnail.d.mts.map
@@ -0,0 +1,17 @@
1
+ //#region src/fields/thumbnail.ts
2
+ const thumbnailField = {
3
+ type: "text",
4
+ name: "thumbnail",
5
+ admin: {
6
+ readOnly: true,
7
+ hidden: true,
8
+ disableListColumn: true,
9
+ disableListFilter: true,
10
+ disableBulkEdit: true,
11
+ disableGroupBy: true
12
+ }
13
+ };
14
+
15
+ //#endregion
16
+ export { thumbnailField };
17
+ //# sourceMappingURL=thumbnail.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thumbnail.mjs","names":["thumbnailField: TextField"],"sources":["../../src/fields/thumbnail.ts"],"sourcesContent":["import { TextField } from 'payload'\n\nexport const thumbnailField: TextField = {\n type: 'text',\n name: 'thumbnail',\n admin: {\n readOnly: true,\n hidden: true,\n disableListColumn: true,\n disableListFilter: true,\n disableBulkEdit: true,\n disableGroupBy: true,\n },\n}\n"],"mappings":";AAEA,MAAaA,iBAA4B;CACvC,MAAM;CACN,MAAM;CACN,OAAO;EACL,UAAU;EACV,QAAQ;EACR,mBAAmB;EACnB,mBAAmB;EACnB,iBAAiB;EACjB,gBAAgB;EACjB;CACF"}
@@ -0,0 +1,7 @@
1
+ import { TextField } from "payload";
2
+
3
+ //#region src/fields/width.d.ts
4
+ declare const widthField: TextField;
5
+ //#endregion
6
+ export { widthField };
7
+ //# sourceMappingURL=width.d.mts.map
@@ -0,0 +1,15 @@
1
+ //#region src/fields/width.ts
2
+ const widthField = {
3
+ name: "width",
4
+ label: "Width",
5
+ type: "text",
6
+ admin: {
7
+ readOnly: true,
8
+ hidden: false,
9
+ width: "50%"
10
+ }
11
+ };
12
+
13
+ //#endregion
14
+ export { widthField };
15
+ //# sourceMappingURL=width.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"width.mjs","names":["widthField: TextField"],"sources":["../../src/fields/width.ts"],"sourcesContent":["import type { TextField } from 'payload'\n\nexport const widthField: TextField = {\n name: 'width',\n label: 'Width',\n type: 'text',\n admin: {\n readOnly: true,\n hidden: false,\n width: '50%',\n },\n}\n"],"mappings":";AAEA,MAAaA,aAAwB;CACnC,MAAM;CACN,OAAO;CACP,MAAM;CACN,OAAO;EACL,UAAU;EACV,QAAQ;EACR,OAAO;EACR;CACF"}
@@ -1,7 +1,7 @@
1
1
  import { UseMagicErrorReturn } from "@maas/error-handler";
2
2
 
3
3
  //#region src/hooks/useErrorHandler.d.ts
4
- declare function useErrorHandler(): Omit<UseMagicErrorReturn, 'assert' | 'MagicError'>;
4
+ declare function useErrorHandler(): Omit<UseMagicErrorReturn, 'MagicError'>;
5
5
  //#endregion
6
6
  export { useErrorHandler };
7
7
  //# sourceMappingURL=useErrorHandler.d.mts.map
@@ -2,12 +2,14 @@ import { useMagicError } from "../error-handler/dist/index.mjs";
2
2
 
3
3
  //#region src/hooks/useErrorHandler.ts
4
4
  function useErrorHandler() {
5
- const { log, logError, throwError, logWarning } = useMagicError({ prefix: "PLUGIN-MEDIA-CLOUD" });
5
+ const magicError = useMagicError({ prefix: "PLUGIN-MEDIA-CLOUD" });
6
+ const { log, logError, throwError, logWarning } = magicError;
6
7
  return {
7
8
  log,
8
9
  logError,
9
10
  throwError,
10
- logWarning
11
+ logWarning,
12
+ assert: magicError.assert
11
13
  };
12
14
  }
13
15
 
@@ -1 +1 @@
1
- {"version":3,"file":"useErrorHandler.mjs","names":[],"sources":["../../src/hooks/useErrorHandler.ts"],"sourcesContent":["import { useMagicError, type UseMagicErrorReturn } from '@maas/error-handler'\n\nexport function useErrorHandler(): Omit<\n UseMagicErrorReturn,\n 'assert' | 'MagicError'\n> {\n const { log, logError, throwError, logWarning } = useMagicError({\n prefix: 'PLUGIN-MEDIA-CLOUD',\n })\n\n return {\n log,\n logError,\n throwError,\n logWarning,\n }\n}\n"],"mappings":";;;AAEA,SAAgB,kBAGd;CACA,MAAM,EAAE,KAAK,UAAU,YAAY,eAAe,cAAc,EAC9D,QAAQ,sBACT,CAAC;AAEF,QAAO;EACL;EACA;EACA;EACA;EACD"}
1
+ {"version":3,"file":"useErrorHandler.mjs","names":["magicError: UseMagicErrorReturn"],"sources":["../../src/hooks/useErrorHandler.ts"],"sourcesContent":["import { useMagicError, type UseMagicErrorReturn } from '@maas/error-handler'\n\nexport function useErrorHandler(): Omit<UseMagicErrorReturn, 'MagicError'> {\n const magicError: UseMagicErrorReturn = useMagicError({\n prefix: 'PLUGIN-MEDIA-CLOUD',\n })\n\n const { log, logError, throwError, logWarning } = magicError\n\n return {\n log,\n logError,\n throwError,\n logWarning,\n assert: magicError.assert,\n }\n}\n"],"mappings":";;;AAEA,SAAgB,kBAA2D;CACzE,MAAMA,aAAkC,cAAc,EACpD,QAAQ,sBACT,CAAC;CAEF,MAAM,EAAE,KAAK,UAAU,YAAY,eAAe;AAElD,QAAO;EACL;EACA;EACA;EACA;EACA,QAAQ,WAAW;EACpB"}
package/dist/plugin.d.mts CHANGED
@@ -1,14 +1,15 @@
1
1
  import { MediaCloudPluginOptions } from "./types/index.mjs";
2
+ import { S3Store } from "./tus/stores/s3/s3Store.mjs";
2
3
  import { Config } from "payload";
3
4
 
4
5
  //#region src/plugin.d.ts
5
-
6
+ declare let s3Store: S3Store | null;
6
7
  /**
7
8
  * Media Cloud Plugin for Payload CMS
8
- * @param pluginOptions Configuration options
9
+ * @param options Configuration options
9
10
  * @returns Payload config function
10
11
  */
11
- declare function mediaCloudPlugin(pluginOptions: MediaCloudPluginOptions): (config: Config) => Config;
12
+ declare function mediaCloudPlugin(options: MediaCloudPluginOptions): (config: Config) => Config;
12
13
  //#endregion
13
- export { mediaCloudPlugin };
14
+ export { mediaCloudPlugin, s3Store };
14
15
  //# sourceMappingURL=plugin.d.mts.map
package/dist/plugin.mjs CHANGED
@@ -3,73 +3,92 @@ import { useErrorHandler } from "./hooks/useErrorHandler.mjs";
3
3
  import { getStorageAdapter } from "./adapter/storageAdapter.mjs";
4
4
  import { getMediaCollection } from "./collections/mediaCollection.mjs";
5
5
  import { createS3Store } from "./tus/stores/s3/index.mjs";
6
- import { createMuxClient, createMuxEndpoints, validateMuxConfig } from "./utils/mux.mjs";
6
+ import { createMuxClient, createMuxEndpoints } from "./utils/mux.mjs";
7
+ import { createFileEndpoints } from "./utils/file.mjs";
7
8
  import { createTusEndpoints, createTusServer } from "./utils/tus.mjs";
9
+ import { defaultOptions } from "./utils/defaultOptions.mjs";
10
+ import { defu } from "defu";
8
11
  import { cloudStoragePlugin } from "@payloadcms/plugin-cloud-storage";
9
12
  import { initClientUploads } from "@payloadcms/plugin-cloud-storage/utilities";
10
13
 
11
14
  //#region src/plugin.ts
12
15
  const { logError } = useErrorHandler();
13
16
  let muxClient = null;
17
+ let s3Store = null;
18
+ let tusServer = null;
14
19
  /**
15
20
  * Media Cloud Plugin for Payload CMS
16
- * @param pluginOptions Configuration options
21
+ * @param options Configuration options
17
22
  * @returns Payload config function
18
23
  */
19
- function mediaCloudPlugin(pluginOptions) {
24
+ function mediaCloudPlugin(options) {
20
25
  return function(config) {
21
- if (!pluginOptions) {
26
+ if (!options) {
22
27
  logError(MediaCloudErrors.PLUGIN_NOT_CONFIGURED.message);
23
28
  return config;
24
29
  }
30
+ const pluginOptions = defu(options, defaultOptions);
25
31
  if (pluginOptions.enabled === false) return config;
26
32
  /**
27
33
  * Helper function to get or create Mux client instance
28
34
  * @returns Mux client instance
29
35
  */
30
36
  function getMuxClient() {
31
- if (muxClient) return muxClient;
32
- return createMuxClient(pluginOptions.mux);
37
+ return muxClient ?? createMuxClient(pluginOptions.mux);
33
38
  }
34
- if (pluginOptions.mux) {
35
- validateMuxConfig(pluginOptions.mux);
36
- muxClient = getMuxClient();
37
- } else {
38
- logError(MediaCloudErrors.MUX_CONFIG_INCOMPLETE.message);
39
- muxClient = null;
39
+ /**
40
+ * Helper function to get or create S3 store instance
41
+ * @returns S3 store instance
42
+ */
43
+ function getS3Store() {
44
+ return s3Store ?? createS3Store(pluginOptions.s3);
45
+ }
46
+ /**
47
+ * Helper function to get or create tus server instance
48
+ * @returns TUS server instance
49
+ */
50
+ function getTusServer() {
51
+ return tusServer ?? createTusServer({
52
+ getS3Store,
53
+ pluginOptions
54
+ });
55
+ }
56
+ if (pluginOptions.mux) muxClient = getMuxClient();
57
+ if (pluginOptions.s3) {
58
+ s3Store = getS3Store();
59
+ tusServer = getTusServer();
40
60
  }
41
- const s3Store = createS3Store(pluginOptions.s3);
42
- const tusServer = createTusServer({
43
- s3Store,
44
- pluginOptions
45
- });
46
61
  const baseCollection = config.collections?.find(({ slug }) => slug === pluginOptions.collection);
62
+ const { view, folders } = pluginOptions;
47
63
  const mediaCollection = getMediaCollection({
48
- s3Store,
49
- baseCollection
64
+ baseCollection,
65
+ view,
66
+ folders
50
67
  });
51
68
  if (baseCollection) config = {
52
69
  ...config,
53
- collections: config.collections?.filter(({ slug }) => slug !== baseCollection?.slug) || []
70
+ collections: config.collections?.filter(({ slug }) => slug !== baseCollection?.slug) ?? []
54
71
  };
55
72
  initClientUploads({
73
+ config,
74
+ enabled: true,
56
75
  clientHandler: "@maas/payload-plugin-media-cloud/components#UploadHandler",
57
- collections: { media: {
76
+ collections: { [mediaCollection.slug]: {
58
77
  clientUploads: true,
59
- disableLocalStorage: true
78
+ disableLocalStorage: true,
79
+ prefix: pluginOptions.s3?.prefix ?? ""
60
80
  } },
61
- config,
62
- enabled: true,
81
+ extraClientHandlerProps: () => ({ pluginOptions }),
63
82
  serverHandler: () => {
64
83
  return Response.json({ message: "Server handler is not implemented" }, { status: 501 });
65
84
  },
66
85
  serverHandlerPath: "/media-cloud/upload"
67
86
  });
68
- const cloudStorageConfig = { collections: { media: {
87
+ const cloudStorageConfig = { collections: { [mediaCollection.slug]: {
69
88
  adapter: getStorageAdapter({
70
89
  getMuxClient,
71
90
  pluginOptions,
72
- s3Store
91
+ getS3Store
73
92
  }),
74
93
  clientUploads: true,
75
94
  disableLocalStorage: true
@@ -87,12 +106,17 @@ function mediaCloudPlugin(pluginOptions) {
87
106
  endpoints: [
88
107
  ...config.endpoints ?? [],
89
108
  ...createTusEndpoints({
90
- tusServer,
91
- s3Store
109
+ getTusServer,
110
+ getS3Store,
111
+ pluginOptions
92
112
  }),
93
113
  ...createMuxEndpoints({
94
114
  getMuxClient,
95
115
  pluginOptions
116
+ }),
117
+ ...createFileEndpoints({
118
+ getS3Store,
119
+ pluginOptions
96
120
  })
97
121
  ]
98
122
  };
@@ -101,5 +125,5 @@ function mediaCloudPlugin(pluginOptions) {
101
125
  }
102
126
 
103
127
  //#endregion
104
- export { mediaCloudPlugin };
128
+ export { mediaCloudPlugin, s3Store };
105
129
  //# sourceMappingURL=plugin.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.mjs","names":["muxClient: Mux | null","mergedConfig: Config"],"sources":["../src/plugin.ts"],"sourcesContent":["import Mux from '@mux/mux-node'\nimport { cloudStoragePlugin } from '@payloadcms/plugin-cloud-storage'\nimport { initClientUploads } from '@payloadcms/plugin-cloud-storage/utilities'\n\nimport { MediaCloudErrors } from './types/errors'\nimport { getStorageAdapter } from './adapter/storageAdapter'\nimport { getMediaCollection } from './collections/mediaCollection'\nimport { useErrorHandler } from './hooks/useErrorHandler'\nimport { createS3Store } from './tus/stores/s3'\nimport {\n createMuxClient,\n createMuxEndpoints,\n validateMuxConfig,\n} from './utils/mux'\nimport { createTusEndpoints, createTusServer } from './utils/tus'\n\nimport type { Config } from 'payload'\nimport type { MediaCloudPluginOptions } from './types'\n\nconst { logError } = useErrorHandler()\n\nlet muxClient: Mux | null = null\n\n/**\n * Media Cloud Plugin for Payload CMS\n * @param pluginOptions Configuration options\n * @returns Payload config function\n */\nexport function mediaCloudPlugin(pluginOptions: MediaCloudPluginOptions) {\n return function (config: Config): Config {\n // Early returns for invalid or disabled plugin configuration\n if (!pluginOptions) {\n logError(MediaCloudErrors.PLUGIN_NOT_CONFIGURED.message)\n return config\n }\n\n if (pluginOptions.enabled === false) {\n return config\n }\n\n /**\n * Helper function to get or create Mux client instance\n * @returns Mux client instance\n */\n function getMuxClient(): Mux {\n if (muxClient) {\n return muxClient\n }\n return createMuxClient(pluginOptions.mux)\n }\n\n // Initialize Mux client if configuration is provided\n if (pluginOptions.mux) {\n validateMuxConfig(pluginOptions.mux)\n muxClient = getMuxClient()\n } else {\n logError(MediaCloudErrors.MUX_CONFIG_INCOMPLETE.message)\n muxClient = null\n }\n\n const s3Store = createS3Store(pluginOptions.s3)\n const tusServer = createTusServer({ s3Store, pluginOptions })\n\n // Handle collection extension - replace base collection if it exists\n const baseCollection = config.collections?.find(\n ({ slug }) => slug === pluginOptions.collection\n )\n\n const mediaCollection = getMediaCollection({\n s3Store,\n baseCollection,\n })\n\n if (baseCollection) {\n config = {\n ...config,\n collections:\n config.collections?.filter(\n ({ slug }) => slug !== baseCollection?.slug\n ) || [],\n }\n }\n\n initClientUploads({\n clientHandler:\n '@maas/payload-plugin-media-cloud/components#UploadHandler',\n collections: {\n media: {\n clientUploads: true,\n disableLocalStorage: true,\n },\n },\n config,\n enabled: true,\n serverHandler: () => {\n return Response.json(\n { message: 'Server handler is not implemented' },\n { status: 501 }\n )\n },\n serverHandlerPath: '/media-cloud/upload',\n })\n\n const cloudStorageConfig = {\n collections: {\n media: {\n adapter: getStorageAdapter({ getMuxClient, pluginOptions, s3Store }),\n clientUploads: true,\n disableLocalStorage: true,\n },\n },\n }\n\n const mergedConfig: Config = {\n ...config,\n admin: {\n ...config.admin,\n components: {\n ...config.admin?.components,\n providers: [\n ...(config.admin?.components?.providers ?? []),\n '@maas/payload-plugin-media-cloud/components#UploadManagerProvider',\n ],\n },\n },\n collections: [...(config.collections ?? []), mediaCollection],\n endpoints: [\n ...(config.endpoints ?? []),\n ...createTusEndpoints({ tusServer, s3Store }),\n ...createMuxEndpoints({ getMuxClient, pluginOptions }),\n ],\n }\n\n return cloudStoragePlugin(cloudStorageConfig)(mergedConfig)\n }\n}\n"],"mappings":";;;;;;;;;;;AAmBA,MAAM,EAAE,aAAa,iBAAiB;AAEtC,IAAIA,YAAwB;;;;;;AAO5B,SAAgB,iBAAiB,eAAwC;AACvE,QAAO,SAAU,QAAwB;AAEvC,MAAI,CAAC,eAAe;AAClB,YAAS,iBAAiB,sBAAsB,QAAQ;AACxD,UAAO;;AAGT,MAAI,cAAc,YAAY,MAC5B,QAAO;;;;;EAOT,SAAS,eAAoB;AAC3B,OAAI,UACF,QAAO;AAET,UAAO,gBAAgB,cAAc,IAAI;;AAI3C,MAAI,cAAc,KAAK;AACrB,qBAAkB,cAAc,IAAI;AACpC,eAAY,cAAc;SACrB;AACL,YAAS,iBAAiB,sBAAsB,QAAQ;AACxD,eAAY;;EAGd,MAAM,UAAU,cAAc,cAAc,GAAG;EAC/C,MAAM,YAAY,gBAAgB;GAAE;GAAS;GAAe,CAAC;EAG7D,MAAM,iBAAiB,OAAO,aAAa,MACxC,EAAE,WAAW,SAAS,cAAc,WACtC;EAED,MAAM,kBAAkB,mBAAmB;GACzC;GACA;GACD,CAAC;AAEF,MAAI,eACF,UAAS;GACP,GAAG;GACH,aACE,OAAO,aAAa,QACjB,EAAE,WAAW,SAAS,gBAAgB,KACxC,IAAI,EAAE;GACV;AAGH,oBAAkB;GAChB,eACE;GACF,aAAa,EACX,OAAO;IACL,eAAe;IACf,qBAAqB;IACtB,EACF;GACD;GACA,SAAS;GACT,qBAAqB;AACnB,WAAO,SAAS,KACd,EAAE,SAAS,qCAAqC,EAChD,EAAE,QAAQ,KAAK,CAChB;;GAEH,mBAAmB;GACpB,CAAC;EAEF,MAAM,qBAAqB,EACzB,aAAa,EACX,OAAO;GACL,SAAS,kBAAkB;IAAE;IAAc;IAAe;IAAS,CAAC;GACpE,eAAe;GACf,qBAAqB;GACtB,EACF,EACF;EAED,MAAMC,eAAuB;GAC3B,GAAG;GACH,OAAO;IACL,GAAG,OAAO;IACV,YAAY;KACV,GAAG,OAAO,OAAO;KACjB,WAAW,CACT,GAAI,OAAO,OAAO,YAAY,aAAa,EAAE,EAC7C,oEACD;KACF;IACF;GACD,aAAa,CAAC,GAAI,OAAO,eAAe,EAAE,EAAG,gBAAgB;GAC7D,WAAW;IACT,GAAI,OAAO,aAAa,EAAE;IAC1B,GAAG,mBAAmB;KAAE;KAAW;KAAS,CAAC;IAC7C,GAAG,mBAAmB;KAAE;KAAc;KAAe,CAAC;IACvD;GACF;AAED,SAAO,mBAAmB,mBAAmB,CAAC,aAAa"}
1
+ {"version":3,"file":"plugin.mjs","names":["muxClient: Mux | null","s3Store: S3Store | null","tusServer: Server | null","mergedConfig: Config"],"sources":["../src/plugin.ts"],"sourcesContent":["import Mux from '@mux/mux-node'\nimport { defu } from 'defu'\nimport { cloudStoragePlugin } from '@payloadcms/plugin-cloud-storage'\nimport { initClientUploads } from '@payloadcms/plugin-cloud-storage/utilities'\n\nimport { MediaCloudErrors } from './types/errors'\nimport { getStorageAdapter } from './adapter/storageAdapter'\nimport { getMediaCollection } from './collections/mediaCollection'\nimport { useErrorHandler } from './hooks/useErrorHandler'\nimport { createS3Store } from './tus/stores/s3'\nimport { createMuxClient, createMuxEndpoints } from './utils/mux'\nimport { createTusEndpoints, createTusServer } from './utils/tus'\nimport { createFileEndpoints } from './utils/file'\nimport { defaultOptions } from './utils/defaultOptions'\n\nimport type { Config } from 'payload'\nimport type { Server } from '@tus/server'\nimport type { MediaCloudPluginOptions } from './types'\nimport type { S3Store } from './tus/stores/s3/s3Store'\n\nconst { logError } = useErrorHandler()\n\nlet muxClient: Mux | null = null\nlet s3Store: S3Store | null = null\nlet tusServer: Server | null = null\n\n/**\n * Media Cloud Plugin for Payload CMS\n * @param options Configuration options\n * @returns Payload config function\n */\nexport function mediaCloudPlugin(options: MediaCloudPluginOptions) {\n return function (config: Config): Config {\n // Check if config is invalid or disabled\n if (!options) {\n logError(MediaCloudErrors.PLUGIN_NOT_CONFIGURED.message)\n return config\n }\n\n // Merge user options with default options\n const pluginOptions = defu(options, defaultOptions)\n\n // Check if the plugin is disabled\n if (pluginOptions.enabled === false) {\n return config\n }\n\n /**\n * Helper function to get or create Mux client instance\n * @returns Mux client instance\n */\n function getMuxClient(): Mux {\n return muxClient ?? createMuxClient(pluginOptions.mux)\n }\n\n /**\n * Helper function to get or create S3 store instance\n * @returns S3 store instance\n */\n function getS3Store(): S3Store {\n return s3Store ?? createS3Store(pluginOptions.s3)\n }\n\n /**\n * Helper function to get or create tus server instance\n * @returns TUS server instance\n */\n function getTusServer(): Server {\n return tusServer ?? createTusServer({ getS3Store, pluginOptions })\n }\n\n // Initialize Mux client if configuration is provided\n if (pluginOptions.mux) {\n muxClient = getMuxClient()\n }\n\n // Initialize S3 store and TUS server if configuration is provided\n if (pluginOptions.s3) {\n s3Store = getS3Store()\n tusServer = getTusServer()\n }\n\n // Check if base collection exists\n const baseCollection = config.collections?.find(\n ({ slug }) => slug === pluginOptions.collection\n )\n\n const { view, folders } = pluginOptions\n\n const mediaCollection = getMediaCollection({\n baseCollection,\n view,\n folders,\n })\n\n // Remove base collection\n // It’ll be replaced with the merged media collection\n if (baseCollection) {\n config = {\n ...config,\n collections:\n config.collections?.filter(\n ({ slug }) => slug !== baseCollection?.slug\n ) ?? [],\n }\n }\n\n initClientUploads({\n config,\n enabled: true,\n clientHandler:\n '@maas/payload-plugin-media-cloud/components#UploadHandler',\n collections: {\n [mediaCollection.slug]: {\n clientUploads: true,\n disableLocalStorage: true,\n prefix: pluginOptions.s3?.prefix ?? '',\n },\n },\n extraClientHandlerProps: () => ({\n pluginOptions,\n }),\n serverHandler: () => {\n return Response.json(\n { message: 'Server handler is not implemented' },\n { status: 501 }\n )\n },\n serverHandlerPath: '/media-cloud/upload',\n })\n\n const cloudStorageConfig = {\n collections: {\n [mediaCollection.slug]: {\n adapter: getStorageAdapter({\n getMuxClient,\n pluginOptions,\n getS3Store,\n }),\n clientUploads: true,\n disableLocalStorage: true,\n },\n },\n }\n\n const mergedConfig: Config = {\n ...config,\n admin: {\n ...config.admin,\n components: {\n ...config.admin?.components,\n providers: [\n ...(config.admin?.components?.providers ?? []),\n '@maas/payload-plugin-media-cloud/components#UploadManagerProvider',\n ],\n },\n },\n collections: [...(config.collections ?? []), mediaCollection],\n endpoints: [\n ...(config.endpoints ?? []),\n ...createTusEndpoints({ getTusServer, getS3Store, pluginOptions }),\n ...createMuxEndpoints({ getMuxClient, pluginOptions }),\n ...createFileEndpoints({ getS3Store, pluginOptions }),\n ],\n }\n\n return cloudStoragePlugin(cloudStorageConfig)(mergedConfig)\n }\n}\n\nexport { s3Store }\n"],"mappings":";;;;;;;;;;;;;;AAoBA,MAAM,EAAE,aAAa,iBAAiB;AAEtC,IAAIA,YAAwB;AAC5B,IAAIC,UAA0B;AAC9B,IAAIC,YAA2B;;;;;;AAO/B,SAAgB,iBAAiB,SAAkC;AACjE,QAAO,SAAU,QAAwB;AAEvC,MAAI,CAAC,SAAS;AACZ,YAAS,iBAAiB,sBAAsB,QAAQ;AACxD,UAAO;;EAIT,MAAM,gBAAgB,KAAK,SAAS,eAAe;AAGnD,MAAI,cAAc,YAAY,MAC5B,QAAO;;;;;EAOT,SAAS,eAAoB;AAC3B,UAAO,aAAa,gBAAgB,cAAc,IAAI;;;;;;EAOxD,SAAS,aAAsB;AAC7B,UAAO,WAAW,cAAc,cAAc,GAAG;;;;;;EAOnD,SAAS,eAAuB;AAC9B,UAAO,aAAa,gBAAgB;IAAE;IAAY;IAAe,CAAC;;AAIpE,MAAI,cAAc,IAChB,aAAY,cAAc;AAI5B,MAAI,cAAc,IAAI;AACpB,aAAU,YAAY;AACtB,eAAY,cAAc;;EAI5B,MAAM,iBAAiB,OAAO,aAAa,MACxC,EAAE,WAAW,SAAS,cAAc,WACtC;EAED,MAAM,EAAE,MAAM,YAAY;EAE1B,MAAM,kBAAkB,mBAAmB;GACzC;GACA;GACA;GACD,CAAC;AAIF,MAAI,eACF,UAAS;GACP,GAAG;GACH,aACE,OAAO,aAAa,QACjB,EAAE,WAAW,SAAS,gBAAgB,KACxC,IAAI,EAAE;GACV;AAGH,oBAAkB;GAChB;GACA,SAAS;GACT,eACE;GACF,aAAa,GACV,gBAAgB,OAAO;IACtB,eAAe;IACf,qBAAqB;IACrB,QAAQ,cAAc,IAAI,UAAU;IACrC,EACF;GACD,gCAAgC,EAC9B,eACD;GACD,qBAAqB;AACnB,WAAO,SAAS,KACd,EAAE,SAAS,qCAAqC,EAChD,EAAE,QAAQ,KAAK,CAChB;;GAEH,mBAAmB;GACpB,CAAC;EAEF,MAAM,qBAAqB,EACzB,aAAa,GACV,gBAAgB,OAAO;GACtB,SAAS,kBAAkB;IACzB;IACA;IACA;IACD,CAAC;GACF,eAAe;GACf,qBAAqB;GACtB,EACF,EACF;EAED,MAAMC,eAAuB;GAC3B,GAAG;GACH,OAAO;IACL,GAAG,OAAO;IACV,YAAY;KACV,GAAG,OAAO,OAAO;KACjB,WAAW,CACT,GAAI,OAAO,OAAO,YAAY,aAAa,EAAE,EAC7C,oEACD;KACF;IACF;GACD,aAAa,CAAC,GAAI,OAAO,eAAe,EAAE,EAAG,gBAAgB;GAC7D,WAAW;IACT,GAAI,OAAO,aAAa,EAAE;IAC1B,GAAG,mBAAmB;KAAE;KAAc;KAAY;KAAe,CAAC;IAClE,GAAG,mBAAmB;KAAE;KAAc;KAAe,CAAC;IACtD,GAAG,oBAAoB;KAAE;KAAY;KAAe,CAAC;IACtD;GACF;AAED,SAAO,mBAAmB,mBAAmB,CAAC,aAAa"}
@@ -1,6 +1,7 @@
1
+ import { S3MetadataManager } from "./metadataManager.mjs";
1
2
  import { S3 } from "@aws-sdk/client-s3";
2
3
 
3
- //#region src/tus/stores/s3/expiration-manager.d.ts
4
+ //#region src/tus/stores/s3/expirationManager.d.ts
4
5
  type GetExpirationDateArgs = {
5
6
  createdAt: string;
6
7
  };
@@ -10,7 +11,7 @@ declare class S3ExpirationManager {
10
11
  private expirationPeriodInMilliseconds;
11
12
  private generateInfoKey;
12
13
  private generatePartKey;
13
- constructor(client: S3, bucket: string, expirationPeriodInMilliseconds: number, generateInfoKey: (id: string) => string, generatePartKey: (id: string, isIncompletePart: boolean) => string);
14
+ constructor(client: S3, bucket: string, expirationPeriodInMilliseconds: number, generateInfoKey: S3MetadataManager['generateInfoKey'], generatePartKey: S3MetadataManager['generatePartKey']);
14
15
  /**
15
16
  * Calculates the expiration date for a file based on a creation date
16
17
  * @param args - The function arguments
@@ -33,4 +34,4 @@ declare class S3ExpirationManager {
33
34
  }
34
35
  //#endregion
35
36
  export { S3ExpirationManager };
36
- //# sourceMappingURL=expiration-manager.d.mts.map
37
+ //# sourceMappingURL=expirationManager.d.mts.map
@@ -1,4 +1,4 @@
1
- //#region src/tus/stores/s3/expiration-manager.ts
1
+ //#region src/tus/stores/s3/expirationManager.ts
2
2
  var S3ExpirationManager = class {
3
3
  constructor(client, bucket, expirationPeriodInMilliseconds, generateInfoKey, generatePartKey) {
4
4
  this.client = client;
@@ -48,7 +48,10 @@ var S3ExpirationManager = class {
48
48
  return initiatedDate && (/* @__PURE__ */ new Date()).getTime() > this.getExpirationDate({ createdAt: initiatedDate.toISOString() }).getTime();
49
49
  }) || [];
50
50
  const objectsToDelete = expiredUploads.reduce((all, expiredUpload) => {
51
- all.push({ Key: this.generateInfoKey(expiredUpload.Key) }, { Key: this.generatePartKey(expiredUpload.Key, true) });
51
+ all.push({ Key: this.generateInfoKey({ id: expiredUpload.Key }) }, { Key: this.generatePartKey({
52
+ id: expiredUpload.Key,
53
+ isIncomplete: true
54
+ }) });
52
55
  return all;
53
56
  }, []);
54
57
  const deletions = [];
@@ -73,4 +76,4 @@ var S3ExpirationManager = class {
73
76
 
74
77
  //#endregion
75
78
  export { S3ExpirationManager };
76
- //# sourceMappingURL=expiration-manager.mjs.map
79
+ //# sourceMappingURL=expirationManager.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expirationManager.mjs","names":["client: S3","bucket: string","expirationPeriodInMilliseconds: number","generateInfoKey: S3MetadataManager['generateInfoKey']","generatePartKey: S3MetadataManager['generatePartKey']","keyMarker: string | undefined","uploadIdMarker: string | undefined","listResponse: AWS.ListMultipartUploadsCommandOutput","deletions: Promise<AWS.DeleteObjectsCommandOutput>[]"],"sources":["../../../../src/tus/stores/s3/expirationManager.ts"],"sourcesContent":["import type AWS from '@aws-sdk/client-s3'\nimport type { S3 } from '@aws-sdk/client-s3'\nimport type { S3MetadataManager } from './metadataManager'\n\ntype GetExpirationDateArgs = {\n createdAt: string\n}\n\nexport class S3ExpirationManager {\n constructor(\n private client: S3,\n private bucket: string,\n private expirationPeriodInMilliseconds: number,\n private generateInfoKey: S3MetadataManager['generateInfoKey'],\n private generatePartKey: S3MetadataManager['generatePartKey']\n ) {}\n\n /**\n * Calculates the expiration date for a file based on a creation date\n * @param args - The function arguments\n * @param args.createdAt - The creation date as a string\n * @returns The expiration date\n */\n getExpirationDate(args: GetExpirationDateArgs): Date {\n const { createdAt } = args\n const date = new Date(createdAt)\n return new Date(date.getTime() + this.expirationPeriodInMilliseconds)\n }\n\n /**\n * Gets the expiration period in milliseconds\n * @returns The expiration period in milliseconds\n */\n getExpiration(): number {\n return this.expirationPeriodInMilliseconds\n }\n\n /**\n * Deletes expired incomplete uploads based on their initialization date.\n * Returns the number of deleted uploads.\n * @param args - The function arguments (empty object)\n * @returns Promise that resolves to the number of deleted uploads\n */\n async deleteExpired(): Promise<number> {\n // No arguments to destructure\n if (this.getExpiration() === 0) {\n return 0\n }\n\n let keyMarker: string | undefined = undefined\n let uploadIdMarker: string | undefined = undefined\n let isTruncated = true\n let deleted = 0\n\n while (isTruncated) {\n const listResponse: AWS.ListMultipartUploadsCommandOutput =\n await this.client.listMultipartUploads({\n Bucket: this.bucket,\n KeyMarker: keyMarker,\n UploadIdMarker: uploadIdMarker,\n })\n\n const expiredUploads =\n listResponse.Uploads?.filter((multiPartUpload: AWS.MultipartUpload) => {\n const initiatedDate = multiPartUpload.Initiated\n return (\n initiatedDate &&\n new Date().getTime() >\n this.getExpirationDate({\n createdAt: initiatedDate.toISOString(),\n }).getTime()\n )\n }) || []\n\n const objectsToDelete = expiredUploads.reduce(\n (all: { Key: string }[], expiredUpload: AWS.MultipartUpload) => {\n all.push(\n {\n Key: this.generateInfoKey({ id: expiredUpload.Key as string }),\n },\n {\n Key: this.generatePartKey({\n id: expiredUpload.Key as string,\n isIncomplete: true,\n }),\n }\n )\n return all\n },\n [] as { Key: string }[]\n )\n\n const deletions: Promise<AWS.DeleteObjectsCommandOutput>[] = []\n\n if (objectsToDelete.length > 0) {\n deletions.push(\n this.client.deleteObjects({\n Bucket: this.bucket,\n Delete: {\n Objects: objectsToDelete,\n },\n })\n )\n }\n\n const abortions = expiredUploads.map(\n (expiredUpload: AWS.MultipartUpload) =>\n this.client.abortMultipartUpload({\n Bucket: this.bucket,\n Key: expiredUpload.Key,\n UploadId: expiredUpload.UploadId,\n })\n )\n\n await Promise.all([...deletions, ...abortions])\n\n deleted += expiredUploads.length\n\n isTruncated = listResponse.IsTruncated || false\n keyMarker = listResponse.NextKeyMarker\n uploadIdMarker = listResponse.NextUploadIdMarker\n }\n\n return deleted\n }\n}\n"],"mappings":";AAQA,IAAa,sBAAb,MAAiC;CAC/B,YACE,AAAQA,QACR,AAAQC,QACR,AAAQC,gCACR,AAAQC,iBACR,AAAQC,iBACR;EALQ;EACA;EACA;EACA;EACA;;;;;;;;CASV,kBAAkB,MAAmC;EACnD,MAAM,EAAE,cAAc;EACtB,MAAM,OAAO,IAAI,KAAK,UAAU;AAChC,SAAO,IAAI,KAAK,KAAK,SAAS,GAAG,KAAK,+BAA+B;;;;;;CAOvE,gBAAwB;AACtB,SAAO,KAAK;;;;;;;;CASd,MAAM,gBAAiC;AAErC,MAAI,KAAK,eAAe,KAAK,EAC3B,QAAO;EAGT,IAAIC,YAAgC;EACpC,IAAIC,iBAAqC;EACzC,IAAI,cAAc;EAClB,IAAI,UAAU;AAEd,SAAO,aAAa;GAClB,MAAMC,eACJ,MAAM,KAAK,OAAO,qBAAqB;IACrC,QAAQ,KAAK;IACb,WAAW;IACX,gBAAgB;IACjB,CAAC;GAEJ,MAAM,iBACJ,aAAa,SAAS,QAAQ,oBAAyC;IACrE,MAAM,gBAAgB,gBAAgB;AACtC,WACE,kCACA,IAAI,MAAM,EAAC,SAAS,GAClB,KAAK,kBAAkB,EACrB,WAAW,cAAc,aAAa,EACvC,CAAC,CAAC,SAAS;KAEhB,IAAI,EAAE;GAEV,MAAM,kBAAkB,eAAe,QACpC,KAAwB,kBAAuC;AAC9D,QAAI,KACF,EACE,KAAK,KAAK,gBAAgB,EAAE,IAAI,cAAc,KAAe,CAAC,EAC/D,EACD,EACE,KAAK,KAAK,gBAAgB;KACxB,IAAI,cAAc;KAClB,cAAc;KACf,CAAC,EACH,CACF;AACD,WAAO;MAET,EAAE,CACH;GAED,MAAMC,YAAuD,EAAE;AAE/D,OAAI,gBAAgB,SAAS,EAC3B,WAAU,KACR,KAAK,OAAO,cAAc;IACxB,QAAQ,KAAK;IACb,QAAQ,EACN,SAAS,iBACV;IACF,CAAC,CACH;GAGH,MAAM,YAAY,eAAe,KAC9B,kBACC,KAAK,OAAO,qBAAqB;IAC/B,QAAQ,KAAK;IACb,KAAK,cAAc;IACnB,UAAU,cAAc;IACzB,CAAC,CACL;AAED,SAAM,QAAQ,IAAI,CAAC,GAAG,WAAW,GAAG,UAAU,CAAC;AAE/C,cAAW,eAAe;AAE1B,iBAAc,aAAa,eAAe;AAC1C,eAAY,aAAa;AACzB,oBAAiB,aAAa;;AAGhC,SAAO"}
@@ -1,6 +1,6 @@
1
1
  import AWS from "@aws-sdk/client-s3";
2
2
 
3
- //#region src/tus/stores/s3/file-operations.d.ts
3
+ //#region src/tus/stores/s3/fileOperations.d.ts
4
4
  type CalculateOptimalPartSizeArgs = {
5
5
  size?: number;
6
6
  };
@@ -63,4 +63,4 @@ declare class S3FileOperations {
63
63
  declare function calculateOffsetFromParts(args: CalculateOffsetFromPartsExportArgs): number;
64
64
  //#endregion
65
65
  export { S3FileOperations, calculateOffsetFromParts };
66
- //# sourceMappingURL=file-operations.d.mts.map
66
+ //# sourceMappingURL=fileOperations.d.mts.map
@@ -5,7 +5,7 @@ import fs from "node:fs";
5
5
  import os from "node:os";
6
6
  import path from "node:path";
7
7
 
8
- //#region src/tus/stores/s3/file-operations.ts
8
+ //#region src/tus/stores/s3/fileOperations.ts
9
9
  const { throwError } = useErrorHandler();
10
10
  var S3FileOperations = class {
11
11
  constructor(maxMultipartParts, maxUploadSize, minPartSize, preferredPartSize) {
@@ -86,4 +86,4 @@ function calculateOffsetFromParts(args) {
86
86
 
87
87
  //#endregion
88
88
  export { S3FileOperations, calculateOffsetFromParts };
89
- //# sourceMappingURL=file-operations.mjs.map
89
+ //# sourceMappingURL=fileOperations.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileOperations.mjs","names":["maxMultipartParts: number","maxUploadSize: number","minPartSize: number","preferredPartSize: number","optimalPartSize: number"],"sources":["../../../../src/tus/stores/s3/fileOperations.ts"],"sourcesContent":["import crypto from 'node:crypto'\nimport fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport { useErrorHandler } from '../../../hooks/useErrorHandler'\nimport { MediaCloudErrors } from '../../../types/errors'\n\nimport type { NodeFSError } from '../../../types'\nimport type AWS from '@aws-sdk/client-s3'\n\ntype CalculateOptimalPartSizeArgs = {\n size?: number\n}\n\ntype CalculateOffsetFromPartsArgs = {\n parts?: Array<AWS.Part>\n}\n\ntype CalculatePartNumberArgs = {\n parts: Array<AWS.Part>\n}\n\ntype GenerateUniqueTmpFileNameArgs = {\n template: string\n}\n\ntype CalculateOffsetFromPartsExportArgs = {\n parts?: Array<{ Size?: number }>\n}\n\nconst { throwError } = useErrorHandler()\n\nexport class S3FileOperations {\n constructor(\n private maxMultipartParts: number,\n private maxUploadSize: number,\n private minPartSize: number,\n private preferredPartSize: number\n ) {}\n\n /**\n * Calculates the optimal part size for S3 multipart upload\n * @param args - The function arguments\n * @param args.size - The upload size in bytes (optional)\n * @returns The optimal part size in bytes\n */\n calculateOptimalPartSize(args: CalculateOptimalPartSizeArgs): number {\n const { size } = args\n // When upload size is not known, default to preferredPartSize\n // Assuming maxUploadSize can lead to extremely large chunks (hundreds of GB),\n // which breaks streaming/resumable uploads in practice\n let uploadSize = size\n if (uploadSize === undefined) {\n uploadSize = this.preferredPartSize\n }\n\n let optimalPartSize: number\n\n // When upload is smaller or equal to preferredPartSize, upload in just one part\n if (uploadSize <= this.preferredPartSize) {\n optimalPartSize = uploadSize\n }\n // Does the upload fit in maxMultipartParts parts or less with preferredPartSize\n else if (uploadSize <= this.preferredPartSize * this.maxMultipartParts) {\n optimalPartSize = this.preferredPartSize\n // The upload is too big for the preferred size\n // We divide the size with the max amount of parts and round it up\n } else {\n optimalPartSize = Math.ceil(uploadSize / this.maxMultipartParts)\n }\n\n // Always ensure the part size is at least minPartSize\n return Math.max(optimalPartSize, this.minPartSize)\n }\n\n /**\n * Calculates the offset based on uploaded parts\n * @param args - The function arguments\n * @param args.parts - Array of uploaded parts (optional)\n * @returns The total offset in bytes\n */\n calculateOffsetFromParts(args: CalculateOffsetFromPartsArgs): number {\n const { parts } = args\n return parts && parts.length > 0\n ? parts.reduce((a, b) => a + (b.Size ?? 0), 0)\n : 0\n }\n\n /**\n * Calculates the next part number based on existing parts\n * @param args - The function arguments\n * @param args.parts - Array of uploaded parts\n * @returns The next part number to use\n */\n calculatePartNumber(args: CalculatePartNumberArgs): number {\n const { parts } = args\n return parts.length > 0 ? parts[parts.length - 1].PartNumber! + 1 : 1\n }\n\n /**\n * Generates a unique temporary file name\n * @param args - The function arguments\n * @param args.template - The template string for the file name\n * @returns Promise that resolves to the unique file path\n * @throws Error if unable to find unique name after max tries\n */\n async generateUniqueTmpFileName(\n args: GenerateUniqueTmpFileNameArgs\n ): Promise<string> {\n const { template } = args\n const tries = 5\n for (let i = 0; i < tries; i++) {\n const randomId = crypto.randomBytes(16).toString('hex')\n const filePath = path.join(os.tmpdir(), `${template}${randomId}`)\n try {\n await fs.promises.access(filePath, fs.constants.F_OK)\n } catch (error) {\n const nodeError = error as NodeFSError\n if (nodeError.code === 'ENOENT') {\n return filePath\n }\n }\n }\n throwError(MediaCloudErrors.S3_UNIQUE_NAME_ERROR)\n throw new Error() // This will never execute but satisfies TypeScript\n }\n}\n\n/**\n * Calculates the total offset from uploaded parts\n * @param args - The function arguments\n * @param args.parts - Array of parts with size information (optional)\n * @returns The total offset in bytes\n */\nexport function calculateOffsetFromParts(\n args: CalculateOffsetFromPartsExportArgs\n) {\n const { parts } = args\n return parts && parts.length > 0\n ? parts.reduce((a, b) => a + (b.Size ?? 0), 0)\n : 0\n}\n"],"mappings":";;;;;;;;AA+BA,MAAM,EAAE,eAAe,iBAAiB;AAExC,IAAa,mBAAb,MAA8B;CAC5B,YACE,AAAQA,mBACR,AAAQC,eACR,AAAQC,aACR,AAAQC,mBACR;EAJQ;EACA;EACA;EACA;;;;;;;;CASV,yBAAyB,MAA4C;EACnE,MAAM,EAAE,SAAS;EAIjB,IAAI,aAAa;AACjB,MAAI,eAAe,OACjB,cAAa,KAAK;EAGpB,IAAIC;AAGJ,MAAI,cAAc,KAAK,kBACrB,mBAAkB;WAGX,cAAc,KAAK,oBAAoB,KAAK,kBACnD,mBAAkB,KAAK;MAIvB,mBAAkB,KAAK,KAAK,aAAa,KAAK,kBAAkB;AAIlE,SAAO,KAAK,IAAI,iBAAiB,KAAK,YAAY;;;;;;;;CASpD,yBAAyB,MAA4C;EACnE,MAAM,EAAE,UAAU;AAClB,SAAO,SAAS,MAAM,SAAS,IAC3B,MAAM,QAAQ,GAAG,MAAM,KAAK,EAAE,QAAQ,IAAI,EAAE,GAC5C;;;;;;;;CASN,oBAAoB,MAAuC;EACzD,MAAM,EAAE,UAAU;AAClB,SAAO,MAAM,SAAS,IAAI,MAAM,MAAM,SAAS,GAAG,aAAc,IAAI;;;;;;;;;CAUtE,MAAM,0BACJ,MACiB;EACjB,MAAM,EAAE,aAAa;EACrB,MAAM,QAAQ;AACd,OAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK;GAC9B,MAAM,WAAW,OAAO,YAAY,GAAG,CAAC,SAAS,MAAM;GACvD,MAAM,WAAW,KAAK,KAAK,GAAG,QAAQ,EAAE,GAAG,WAAW,WAAW;AACjE,OAAI;AACF,UAAM,GAAG,SAAS,OAAO,UAAU,GAAG,UAAU,KAAK;YAC9C,OAAO;AAEd,QADkB,MACJ,SAAS,SACrB,QAAO;;;AAIb,aAAW,iBAAiB,qBAAqB;AACjD,QAAM,IAAI,OAAO;;;;;;;;;AAUrB,SAAgB,yBACd,MACA;CACA,MAAM,EAAE,UAAU;AAClB,QAAO,SAAS,MAAM,SAAS,IAC3B,MAAM,QAAQ,GAAG,MAAM,KAAK,EAAE,QAAQ,IAAI,EAAE,GAC5C"}
@@ -1,5 +1,5 @@
1
1
  import { MediaCloudPluginOptions } from "../../../types/index.mjs";
2
- import { S3Store } from "./s3-store.mjs";
2
+ import { S3Store } from "./s3Store.mjs";
3
3
 
4
4
  //#region src/tus/stores/s3/index.d.ts
5
5
 
@@ -1,9 +1,20 @@
1
1
  import { MediaCloudErrors } from "../../../types/errors.mjs";
2
- import { useErrorHandler } from "../../../hooks/useErrorHandler.mjs";
3
- import { S3Store } from "./s3-store.mjs";
2
+ import { useMagicError } from "../../../error-handler/dist/index.mjs";
3
+ import { S3Store } from "./s3Store.mjs";
4
4
 
5
5
  //#region src/tus/stores/s3/index.ts
6
- const { throwError } = useErrorHandler();
6
+ const magicError = useMagicError({ prefix: "PLUGIN-MEDIA-CLOUD" });
7
+ /**
8
+ * Validates S3 configuration options
9
+ * @param s3Config - The S3 configuration to validate
10
+ * @throws {Error} When required S3 configuration is missing
11
+ */
12
+ function validateS3Config(s3Config) {
13
+ magicError.assert(s3Config?.bucket, MediaCloudErrors.S3_CONFIG_MISSING);
14
+ magicError.assert(s3Config?.region, MediaCloudErrors.S3_CONFIG_MISSING);
15
+ magicError.assert(s3Config?.accessKeyId, MediaCloudErrors.S3_CONFIG_MISSING);
16
+ magicError.assert(s3Config?.secretAccessKey, MediaCloudErrors.S3_CONFIG_MISSING);
17
+ }
7
18
  /**
8
19
  * Creates and configures an S3Store instance
9
20
  * @param s3Config - The S3 configuration options
@@ -11,17 +22,17 @@ const { throwError } = useErrorHandler();
11
22
  * @throws {Error} When required S3 configuration is missing
12
23
  */
13
24
  function createS3Store(s3Config) {
14
- if (!s3Config?.bucket || !s3Config?.region || !s3Config?.accessKeyId || !s3Config?.secretAccessKey) throwError(MediaCloudErrors.S3_CONFIG_MISSING);
25
+ validateS3Config(s3Config);
15
26
  return new S3Store({ s3ClientConfig: {
16
27
  acl: "public-read",
17
- bucket: s3Config.bucket,
28
+ bucket: s3Config?.bucket ?? "",
18
29
  credentials: {
19
- accessKeyId: s3Config.accessKeyId,
20
- secretAccessKey: s3Config.secretAccessKey
30
+ accessKeyId: s3Config?.accessKeyId ?? "",
31
+ secretAccessKey: s3Config?.secretAccessKey ?? ""
21
32
  },
22
- endpoint: s3Config.endpoint,
33
+ endpoint: s3Config?.endpoint ?? "",
23
34
  forcePathStyle: true,
24
- region: s3Config.region
35
+ region: s3Config?.region ?? ""
25
36
  } });
26
37
  }
27
38
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/tus/stores/s3/index.ts"],"sourcesContent":["import { MediaCloudErrors } from '../../../types/errors'\nimport { S3Store } from './s3-store'\nimport { useErrorHandler } from '../../../hooks/useErrorHandler'\n\nimport type { MediaCloudPluginOptions } from '../../../types'\n\nconst { throwError } = useErrorHandler()\n\n/**\n * Creates and configures an S3Store instance\n * @param s3Config - The S3 configuration options\n * @returns A configured S3Store instance\n * @throws {Error} When required S3 configuration is missing\n */\nexport function createS3Store(\n s3Config: MediaCloudPluginOptions['s3']\n): S3Store {\n // Validate S3 configuration\n if (\n !s3Config?.bucket ||\n !s3Config?.region ||\n !s3Config?.accessKeyId ||\n !s3Config?.secretAccessKey\n ) {\n throwError(MediaCloudErrors.S3_CONFIG_MISSING)\n }\n\n // Create and return S3Store instance\n return new S3Store({\n s3ClientConfig: {\n acl: 'public-read',\n bucket: s3Config.bucket,\n credentials: {\n accessKeyId: s3Config.accessKeyId,\n secretAccessKey: s3Config.secretAccessKey,\n },\n endpoint: s3Config.endpoint,\n forcePathStyle: true,\n region: s3Config.region,\n },\n })\n}\n"],"mappings":";;;;;AAMA,MAAM,EAAE,eAAe,iBAAiB;;;;;;;AAQxC,SAAgB,cACd,UACS;AAET,KACE,CAAC,UAAU,UACX,CAAC,UAAU,UACX,CAAC,UAAU,eACX,CAAC,UAAU,gBAEX,YAAW,iBAAiB,kBAAkB;AAIhD,QAAO,IAAI,QAAQ,EACjB,gBAAgB;EACd,KAAK;EACL,QAAQ,SAAS;EACjB,aAAa;GACX,aAAa,SAAS;GACtB,iBAAiB,SAAS;GAC3B;EACD,UAAU,SAAS;EACnB,gBAAgB;EAChB,QAAQ,SAAS;EAClB,EACF,CAAC"}
1
+ {"version":3,"file":"index.mjs","names":["magicError: UseMagicErrorReturn"],"sources":["../../../../src/tus/stores/s3/index.ts"],"sourcesContent":["import { MediaCloudErrors } from '../../../types/errors'\nimport { S3Store } from './s3Store'\nimport { useMagicError } from '@maas/error-handler'\n\nimport type { MediaCloudPluginOptions } from '../../../types'\nimport type { UseMagicErrorReturn } from '@maas/error-handler'\n\nconst magicError: UseMagicErrorReturn = useMagicError({\n prefix: 'PLUGIN-MEDIA-CLOUD',\n})\n\n/**\n * Validates S3 configuration options\n * @param s3Config - The S3 configuration to validate\n * @throws {Error} When required S3 configuration is missing\n */\nfunction validateS3Config(s3Config: MediaCloudPluginOptions['s3']): void {\n magicError.assert(s3Config?.bucket, MediaCloudErrors.S3_CONFIG_MISSING)\n magicError.assert(s3Config?.region, MediaCloudErrors.S3_CONFIG_MISSING)\n magicError.assert(s3Config?.accessKeyId, MediaCloudErrors.S3_CONFIG_MISSING)\n magicError.assert(\n s3Config?.secretAccessKey,\n MediaCloudErrors.S3_CONFIG_MISSING\n )\n}\n\n/**\n * Creates and configures an S3Store instance\n * @param s3Config - The S3 configuration options\n * @returns A configured S3Store instance\n * @throws {Error} When required S3 configuration is missing\n */\nexport function createS3Store(\n s3Config: MediaCloudPluginOptions['s3']\n): S3Store {\n validateS3Config(s3Config)\n\n return new S3Store({\n s3ClientConfig: {\n acl: 'public-read',\n bucket: s3Config?.bucket ?? '',\n credentials: {\n accessKeyId: s3Config?.accessKeyId ?? '',\n secretAccessKey: s3Config?.secretAccessKey ?? '',\n },\n endpoint: s3Config?.endpoint ?? '',\n forcePathStyle: true,\n region: s3Config?.region ?? '',\n },\n })\n}\n"],"mappings":";;;;;AAOA,MAAMA,aAAkC,cAAc,EACpD,QAAQ,sBACT,CAAC;;;;;;AAOF,SAAS,iBAAiB,UAA+C;AACvE,YAAW,OAAO,UAAU,QAAQ,iBAAiB,kBAAkB;AACvE,YAAW,OAAO,UAAU,QAAQ,iBAAiB,kBAAkB;AACvE,YAAW,OAAO,UAAU,aAAa,iBAAiB,kBAAkB;AAC5E,YAAW,OACT,UAAU,iBACV,iBAAiB,kBAClB;;;;;;;;AASH,SAAgB,cACd,UACS;AACT,kBAAiB,SAAS;AAE1B,QAAO,IAAI,QAAQ,EACjB,gBAAgB;EACd,KAAK;EACL,QAAQ,UAAU,UAAU;EAC5B,aAAa;GACX,aAAa,UAAU,eAAe;GACtC,iBAAiB,UAAU,mBAAmB;GAC/C;EACD,UAAU,UAAU,YAAY;EAChC,gBAAgB;EAChB,QAAQ,UAAU,UAAU;EAC7B,EACF,CAAC"}
@@ -2,12 +2,13 @@ import { TusUploadMetadata } from "../../../types/index.mjs";
2
2
  import { S3 } from "@aws-sdk/client-s3";
3
3
  import { Upload } from "@tus/utils";
4
4
 
5
- //#region src/tus/stores/s3/metadata-manager.d.ts
5
+ //#region src/tus/stores/s3/metadataManager.d.ts
6
6
  type GenerateInfoKeyArgs = {
7
7
  id: string;
8
8
  };
9
9
  type GeneratePartKeyArgs = {
10
10
  id: string;
11
+ prefix?: string;
11
12
  isIncomplete?: boolean;
12
13
  };
13
14
  type GetMetadataArgs = {
@@ -37,6 +38,7 @@ declare class S3MetadataManager {
37
38
  * Generates the S3 key for part files
38
39
  * @param args - The function arguments
39
40
  * @param args.id - The file ID
41
+ * @param args.prefix - Path prefix for nested media items
40
42
  * @param args.isIncomplete - Whether this is an incomplete part
41
43
  * @returns The S3 key for the part file
42
44
  */
@@ -68,4 +70,4 @@ declare class S3MetadataManager {
68
70
  }
69
71
  //#endregion
70
72
  export { S3MetadataManager };
71
- //# sourceMappingURL=metadata-manager.d.mts.map
73
+ //# sourceMappingURL=metadataManager.d.mts.map
@@ -2,7 +2,7 @@ import { MediaCloudLogs } from "../../../types/errors.mjs";
2
2
  import { useErrorHandler } from "../../../hooks/useErrorHandler.mjs";
3
3
  import { TUS_RESUMABLE, Upload } from "@tus/utils";
4
4
 
5
- //#region src/tus/stores/s3/metadata-manager.ts
5
+ //#region src/tus/stores/s3/metadataManager.ts
6
6
  const { log } = useErrorHandler();
7
7
  var S3MetadataManager = class {
8
8
  constructor(client, bucket, shouldUseExpirationTags, generateCompleteTag) {
@@ -18,19 +18,20 @@ var S3MetadataManager = class {
18
18
  * @returns The S3 key for the metadata file
19
19
  */
20
20
  generateInfoKey(args) {
21
- const { id } = args;
22
- return `${id}.info`;
21
+ return `${args.id}.info`;
23
22
  }
24
23
  /**
25
24
  * Generates the S3 key for part files
26
25
  * @param args - The function arguments
27
26
  * @param args.id - The file ID
27
+ * @param args.prefix - Path prefix for nested media items
28
28
  * @param args.isIncomplete - Whether this is an incomplete part
29
29
  * @returns The S3 key for the part file
30
30
  */
31
31
  generatePartKey(args) {
32
- const { id, isIncomplete = false } = args;
32
+ const { id, prefix, isIncomplete = false } = args;
33
33
  let key = id;
34
+ if (prefix) key = `${prefix}/${key}`;
34
35
  if (isIncomplete) key += ".part";
35
36
  return key;
36
37
  }
@@ -110,4 +111,4 @@ var S3MetadataManager = class {
110
111
 
111
112
  //#endregion
112
113
  export { S3MetadataManager };
113
- //# sourceMappingURL=metadata-manager.mjs.map
114
+ //# sourceMappingURL=metadataManager.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadataManager.mjs","names":["client: S3","bucket: string","shouldUseExpirationTags: () => boolean","generateCompleteTag: (value: 'false' | 'true') => string | undefined"],"sources":["../../../../src/tus/stores/s3/metadataManager.ts"],"sourcesContent":["import { TUS_RESUMABLE, Upload } from '@tus/utils'\n\nimport { useErrorHandler } from '../../../hooks/useErrorHandler'\nimport { MediaCloudLogs } from '../../../types/errors'\n\nimport type { S3 } from '@aws-sdk/client-s3'\nimport type { TusUploadMetadata } from '../../../types'\n\ntype GenerateInfoKeyArgs = {\n id: string\n}\n\ntype GeneratePartKeyArgs = {\n id: string\n prefix?: string\n isIncomplete?: boolean\n}\n\ntype GetMetadataArgs = {\n id: string\n}\n\ntype SaveMetadataArgs = {\n upload: Upload\n uploadId: string\n}\n\ntype CompleteMetadataArgs = {\n upload: Upload\n}\n\nconst { log } = useErrorHandler()\n\nexport class S3MetadataManager {\n constructor(\n private client: S3,\n private bucket: string,\n private shouldUseExpirationTags: () => boolean,\n private generateCompleteTag: (value: 'false' | 'true') => string | undefined\n ) {}\n /**\n * Generates the S3 key for metadata info files\n * @param args - The function arguments\n * @param args.id - The file ID\n * @returns The S3 key for the metadata file\n */\n generateInfoKey(args: GenerateInfoKeyArgs): string {\n return `${args.id}.info`\n }\n\n /**\n * Generates the S3 key for part files\n * @param args - The function arguments\n * @param args.id - The file ID\n * @param args.prefix - Path prefix for nested media items\n * @param args.isIncomplete - Whether this is an incomplete part\n * @returns The S3 key for the part file\n */\n generatePartKey(args: GeneratePartKeyArgs): string {\n const { id, prefix, isIncomplete = false } = args\n let key = id\n\n if (prefix) {\n key = `${prefix}/${key}`\n }\n\n if (isIncomplete) {\n key += '.part'\n }\n\n // TODO: introduce ObjectPrefixing for parts and incomplete parts\n // ObjectPrefix is prepended to the name of each S3 object that is created\n // to store uploaded files. It can be used to create a pseudo-directory\n // structure in the bucket, e.g. \"path/to/my/uploads\".\n return key\n }\n\n /**\n * Retrieves upload metadata previously saved in `${file_id}.info`.\n * Always fetches fresh data from S3 to ensure correctness.\n * @param args - The function arguments\n * @param args.id - The file ID to retrieve metadata for\n * @returns Promise that resolves to the upload metadata\n */\n async getMetadata(args: GetMetadataArgs): Promise<TusUploadMetadata> {\n const { id } = args\n\n const { Body, Metadata } = await this.client.getObject({\n Bucket: this.bucket,\n Key: this.generateInfoKey({ id }),\n })\n\n const file = JSON.parse((await Body?.transformToString()) as string)\n\n const parsedSize =\n file.size === undefined || file.size === null\n ? undefined\n : Number(file.size)\n\n const metadata: TusUploadMetadata = {\n file: new Upload({\n id,\n creation_date: file.creation_date,\n metadata: file.metadata,\n offset: Number.parseInt(file.offset, 10),\n size: Number.isFinite(parsedSize) ? parsedSize : undefined,\n storage: file.storage,\n }),\n 'tus-version': Metadata?.['tus-version'] as string,\n 'upload-id': (Metadata?.['upload-id'] || file['upload-id']) as string,\n }\n\n return metadata\n }\n\n /**\n * Saves upload metadata to a `${file_id}.info` file on S3.\n * The upload-id is stored in the S3 object metadata.\n * @param args - The function arguments\n * @param args.upload - The upload object containing metadata\n * @param args.uploadId - The upload ID for the multipart upload\n * @returns Promise that resolves when metadata is saved\n */\n async saveMetadata(args: SaveMetadataArgs): Promise<void> {\n const { upload, uploadId } = args\n log(MediaCloudLogs.S3_STORE_METADATA_SAVING)\n\n await this.client.putObject({\n Body: JSON.stringify(upload),\n Bucket: this.bucket,\n Key: this.generateInfoKey({ id: upload.id }),\n Metadata: {\n 'tus-version': TUS_RESUMABLE,\n 'upload-id': uploadId,\n },\n Tagging: this.generateCompleteTag('false'),\n })\n log(MediaCloudLogs.S3_STORE_METADATA_SAVED)\n }\n\n /**\n * Completes metadata by updating it with completion tags\n * @param args - The function arguments\n * @param args.upload - The completed upload object\n * @returns Promise that resolves when metadata is updated\n */\n async completeMetadata(args: CompleteMetadataArgs): Promise<void> {\n const { upload } = args\n\n if (!this.shouldUseExpirationTags()) {\n return\n }\n\n const metadata = await this.getMetadata({ id: upload.id })\n const { 'upload-id': uploadId } = metadata\n\n await this.client.putObject({\n Body: JSON.stringify(upload),\n Bucket: this.bucket,\n Key: this.generateInfoKey({ id: upload.id }),\n Metadata: {\n 'tus-version': TUS_RESUMABLE,\n 'upload-id': uploadId,\n },\n Tagging: this.generateCompleteTag('true'),\n })\n }\n}\n"],"mappings":";;;;;AA+BA,MAAM,EAAE,QAAQ,iBAAiB;AAEjC,IAAa,oBAAb,MAA+B;CAC7B,YACE,AAAQA,QACR,AAAQC,QACR,AAAQC,yBACR,AAAQC,qBACR;EAJQ;EACA;EACA;EACA;;;;;;;;CAQV,gBAAgB,MAAmC;AACjD,SAAO,GAAG,KAAK,GAAG;;;;;;;;;;CAWpB,gBAAgB,MAAmC;EACjD,MAAM,EAAE,IAAI,QAAQ,eAAe,UAAU;EAC7C,IAAI,MAAM;AAEV,MAAI,OACF,OAAM,GAAG,OAAO,GAAG;AAGrB,MAAI,aACF,QAAO;AAOT,SAAO;;;;;;;;;CAUT,MAAM,YAAY,MAAmD;EACnE,MAAM,EAAE,OAAO;EAEf,MAAM,EAAE,MAAM,aAAa,MAAM,KAAK,OAAO,UAAU;GACrD,QAAQ,KAAK;GACb,KAAK,KAAK,gBAAgB,EAAE,IAAI,CAAC;GAClC,CAAC;EAEF,MAAM,OAAO,KAAK,MAAO,MAAM,MAAM,mBAAmB,CAAY;EAEpE,MAAM,aACJ,KAAK,SAAS,UAAa,KAAK,SAAS,OACrC,SACA,OAAO,KAAK,KAAK;AAevB,SAboC;GAClC,MAAM,IAAI,OAAO;IACf;IACA,eAAe,KAAK;IACpB,UAAU,KAAK;IACf,QAAQ,OAAO,SAAS,KAAK,QAAQ,GAAG;IACxC,MAAM,OAAO,SAAS,WAAW,GAAG,aAAa;IACjD,SAAS,KAAK;IACf,CAAC;GACF,eAAe,WAAW;GAC1B,aAAc,WAAW,gBAAgB,KAAK;GAC/C;;;;;;;;;;CAaH,MAAM,aAAa,MAAuC;EACxD,MAAM,EAAE,QAAQ,aAAa;AAC7B,MAAI,eAAe,yBAAyB;AAE5C,QAAM,KAAK,OAAO,UAAU;GAC1B,MAAM,KAAK,UAAU,OAAO;GAC5B,QAAQ,KAAK;GACb,KAAK,KAAK,gBAAgB,EAAE,IAAI,OAAO,IAAI,CAAC;GAC5C,UAAU;IACR,eAAe;IACf,aAAa;IACd;GACD,SAAS,KAAK,oBAAoB,QAAQ;GAC3C,CAAC;AACF,MAAI,eAAe,wBAAwB;;;;;;;;CAS7C,MAAM,iBAAiB,MAA2C;EAChE,MAAM,EAAE,WAAW;AAEnB,MAAI,CAAC,KAAK,yBAAyB,CACjC;EAIF,MAAM,EAAE,aAAa,aADJ,MAAM,KAAK,YAAY,EAAE,IAAI,OAAO,IAAI,CAAC;AAG1D,QAAM,KAAK,OAAO,UAAU;GAC1B,MAAM,KAAK,UAAU,OAAO;GAC5B,QAAQ,KAAK;GACb,KAAK,KAAK,gBAAgB,EAAE,IAAI,OAAO,IAAI,CAAC;GAC5C,UAAU;IACR,eAAe;IACf,aAAa;IACd;GACD,SAAS,KAAK,oBAAoB,OAAO;GAC1C,CAAC"}
@@ -1,12 +1,12 @@
1
1
  import { Semaphore } from "./semaphore.mjs";
2
- import { S3FileOperations } from "./file-operations.mjs";
3
2
  import { IncompletePartInfo, TusUploadMetadata } from "../../../types/index.mjs";
4
- import { S3MetadataManager } from "./metadata-manager.mjs";
3
+ import { S3MetadataManager } from "./metadataManager.mjs";
4
+ import { S3FileOperations } from "./fileOperations.mjs";
5
5
  import stream, { Readable } from "node:stream";
6
6
  import AWS, { S3 } from "@aws-sdk/client-s3";
7
7
  import fs from "node:fs";
8
8
 
9
- //#region src/tus/stores/s3/parts-manager.d.ts
9
+ //#region src/tus/stores/s3/partsManager.d.ts
10
10
  type RetrievePartsArgs = {
11
11
  id: string;
12
12
  partNumberMarker?: string;
@@ -127,4 +127,4 @@ declare class S3PartsManager {
127
127
  }
128
128
  //#endregion
129
129
  export { S3PartsManager };
130
- //# sourceMappingURL=parts-manager.d.mts.map
130
+ //# sourceMappingURL=partsManager.d.mts.map