@maas/payload-plugin-media-cloud 0.0.31 → 0.0.33
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.
- package/dist/adapter/handleDelete.d.mts +3 -3
- package/dist/adapter/handleDelete.mjs +6 -6
- package/dist/adapter/handleDelete.mjs.map +1 -1
- package/dist/adapter/handleUpload.mjs.map +1 -1
- package/dist/adapter/staticHandler.d.mts +5 -3
- package/dist/adapter/staticHandler.mjs +8 -7
- package/dist/adapter/staticHandler.mjs.map +1 -1
- package/dist/adapter/storageAdapter.d.mts +3 -3
- package/dist/adapter/storageAdapter.mjs +4 -4
- package/dist/adapter/storageAdapter.mjs.map +1 -1
- package/dist/collectionHooks/afterChange.d.mts +7 -0
- package/dist/collectionHooks/afterChange.mjs +39 -0
- package/dist/collectionHooks/afterChange.mjs.map +1 -0
- package/dist/collectionHooks/beforeChange.d.mts +7 -0
- package/dist/collectionHooks/beforeChange.mjs +33 -0
- package/dist/collectionHooks/beforeChange.mjs.map +1 -0
- package/dist/collections/mediaCollection.d.mts +3 -2
- package/dist/collections/mediaCollection.mjs +36 -187
- package/dist/collections/mediaCollection.mjs.map +1 -1
- package/dist/components/folderFileCard/folderFileCard.d.mts +13 -0
- package/dist/components/folderFileCard/folderFileCard.mjs +75 -0
- package/dist/components/folderFileCard/folderFileCard.mjs.map +1 -0
- package/dist/components/gridContext/gridContext.d.mts +51 -0
- package/dist/components/gridContext/gridContext.mjs +227 -0
- package/dist/components/gridContext/gridContext.mjs.map +1 -0
- package/dist/components/gridView/gridView.css +50 -0
- package/dist/components/gridView/gridView.d.mts +16 -0
- package/dist/components/gridView/gridView.mjs +283 -0
- package/dist/components/gridView/gridView.mjs.map +1 -0
- package/dist/components/gridView/index.d.mts +2 -0
- package/dist/components/gridView/index.mjs +3 -0
- package/dist/components/index.d.mts +9 -7
- package/dist/components/index.mjs +5 -4
- package/dist/components/itemCardGrid/itemCardGrid.css +12 -0
- package/dist/components/itemCardGrid/itemCardGrid.d.mts +18 -0
- package/dist/components/itemCardGrid/itemCardGrid.mjs +42 -0
- package/dist/components/itemCardGrid/itemCardGrid.mjs.map +1 -0
- package/dist/components/muxPreview/index.d.mts +2 -0
- package/dist/components/muxPreview/index.mjs +3 -0
- package/dist/components/{mux-preview/mux-preview.d.mts → muxPreview/muxPreview.d.mts} +2 -2
- package/dist/components/muxPreview/muxPreview.mjs +65 -0
- package/dist/components/muxPreview/muxPreview.mjs.map +1 -0
- package/dist/components/uploadHandler/index.d.mts +2 -0
- package/dist/components/uploadHandler/index.mjs +3 -0
- package/dist/components/uploadHandler/uploadHandler.d.mts +20 -0
- package/dist/components/{upload-handler/upload-handler.mjs → uploadHandler/uploadHandler.mjs} +82 -52
- package/dist/components/uploadHandler/uploadHandler.mjs.map +1 -0
- package/dist/components/uploadManager/index.d.mts +2 -0
- package/dist/components/uploadManager/index.mjs +3 -0
- package/dist/components/{upload-manager/upload-manager.d.mts → uploadManager/uploadManager.d.mts} +3 -3
- package/dist/components/uploadManager/uploadManager.mjs +363 -0
- package/dist/components/uploadManager/uploadManager.mjs.map +1 -0
- package/dist/endpoints/fileExistsHandler.d.mts +12 -0
- package/dist/endpoints/{tusFileExistsHandler.mjs → fileExistsHandler.mjs} +7 -7
- package/dist/endpoints/fileExistsHandler.mjs.map +1 -0
- package/dist/endpoints/muxAssetHandler.d.mts +1 -0
- package/dist/endpoints/muxAssetHandler.mjs +3 -3
- package/dist/endpoints/muxAssetHandler.mjs.map +1 -1
- package/dist/endpoints/muxCreateUploadHandler.mjs.map +1 -1
- package/dist/endpoints/muxWebhookHandler.d.mts +1 -0
- package/dist/endpoints/muxWebhookHandler.mjs +6 -5
- package/dist/endpoints/muxWebhookHandler.mjs.map +1 -1
- package/dist/endpoints/tusCleanupHandler.d.mts +3 -2
- package/dist/endpoints/tusCleanupHandler.mjs +4 -4
- package/dist/endpoints/tusCleanupHandler.mjs.map +1 -1
- package/dist/endpoints/tusFolderHandler.d.mts +12 -0
- package/dist/endpoints/tusFolderHandler.mjs +39 -0
- package/dist/endpoints/tusFolderHandler.mjs.map +1 -0
- package/dist/endpoints/tusPostProcessorHandler.d.mts +3 -2
- package/dist/endpoints/tusPostProcessorHandler.mjs +6 -5
- package/dist/endpoints/tusPostProcessorHandler.mjs.map +1 -1
- package/dist/fields/alt.d.mts +7 -0
- package/dist/fields/alt.mjs +10 -0
- package/dist/fields/alt.mjs.map +1 -0
- package/dist/fields/filename.d.mts +7 -0
- package/dist/fields/filename.mjs +14 -0
- package/dist/fields/filename.mjs.map +1 -0
- package/dist/fields/height.d.mts +7 -0
- package/dist/fields/height.mjs +15 -0
- package/dist/fields/height.mjs.map +1 -0
- package/dist/fields/mux.d.mts +7 -0
- package/dist/fields/mux.mjs +149 -0
- package/dist/fields/mux.mjs.map +1 -0
- package/dist/fields/path.d.mts +7 -0
- package/dist/fields/path.mjs +14 -0
- package/dist/fields/path.mjs.map +1 -0
- package/dist/fields/storage.d.mts +7 -0
- package/dist/fields/storage.mjs +18 -0
- package/dist/fields/storage.mjs.map +1 -0
- package/dist/fields/thumbnail.d.mts +7 -0
- package/dist/fields/thumbnail.mjs +17 -0
- package/dist/fields/thumbnail.mjs.map +1 -0
- package/dist/fields/width.d.mts +7 -0
- package/dist/fields/width.mjs +15 -0
- package/dist/fields/width.mjs.map +1 -0
- package/dist/hooks/useErrorHandler.d.mts +1 -1
- package/dist/hooks/useErrorHandler.mjs +26 -7
- package/dist/hooks/useErrorHandler.mjs.map +1 -1
- package/dist/hooks/useMediaCloudEmitter.mjs.map +1 -1
- package/dist/plugin.d.mts +5 -4
- package/dist/plugin.mjs +53 -29
- package/dist/plugin.mjs.map +1 -1
- package/dist/tus/stores/s3/{expiration-manager.d.mts → expirationManager.d.mts} +4 -3
- package/dist/tus/stores/s3/{expiration-manager.mjs → expirationManager.mjs} +6 -3
- package/dist/tus/stores/s3/expirationManager.mjs.map +1 -0
- package/dist/tus/stores/s3/{file-operations.d.mts → fileOperations.d.mts} +2 -2
- package/dist/tus/stores/s3/{file-operations.mjs → fileOperations.mjs} +2 -2
- package/dist/tus/stores/s3/fileOperations.mjs.map +1 -0
- package/dist/tus/stores/s3/index.d.mts +1 -1
- package/dist/tus/stores/s3/index.mjs +20 -9
- package/dist/tus/stores/s3/index.mjs.map +1 -1
- package/dist/tus/stores/s3/{metadata-manager.d.mts → metadataManager.d.mts} +4 -2
- package/dist/tus/stores/s3/{metadata-manager.mjs → metadataManager.mjs} +6 -5
- package/dist/tus/stores/s3/metadataManager.mjs.map +1 -0
- package/dist/tus/stores/s3/{parts-manager.d.mts → partsManager.d.mts} +4 -4
- package/dist/tus/stores/s3/{parts-manager.mjs → partsManager.mjs} +67 -29
- package/dist/tus/stores/s3/partsManager.mjs.map +1 -0
- package/dist/tus/stores/s3/{s3-store.d.mts → s3Store.d.mts} +38 -32
- package/dist/tus/stores/s3/{s3-store.mjs → s3Store.mjs} +104 -59
- package/dist/tus/stores/s3/s3Store.mjs.map +1 -0
- package/dist/tus/stores/s3/semaphore.mjs.map +1 -1
- package/dist/types/errors.d.mts +32 -0
- package/dist/types/errors.mjs +32 -0
- package/dist/types/errors.mjs.map +1 -1
- package/dist/types/index.d.mts +42 -4
- package/dist/utils/buildS3Path.d.mts +10 -0
- package/dist/utils/buildS3Path.mjs +16 -0
- package/dist/utils/buildS3Path.mjs.map +1 -0
- package/dist/utils/buildThumbnailURL.d.mts +14 -0
- package/dist/utils/buildThumbnailURL.mjs +10 -0
- package/dist/utils/buildThumbnailURL.mjs.map +1 -0
- package/dist/utils/defaultOptions.d.mts +7 -0
- package/dist/utils/defaultOptions.mjs +12 -0
- package/dist/utils/defaultOptions.mjs.map +1 -0
- package/dist/utils/file.d.mts +16 -2
- package/dist/utils/file.mjs +58 -6
- package/dist/utils/file.mjs.map +1 -1
- package/dist/utils/mux.mjs +19 -8
- package/dist/utils/mux.mjs.map +1 -1
- package/dist/utils/tus.d.mts +9 -6
- package/dist/utils/tus.mjs +31 -11
- package/dist/utils/tus.mjs.map +1 -1
- package/package.json +11 -4
- package/dist/components/mux-preview/index.d.mts +0 -2
- package/dist/components/mux-preview/index.mjs +0 -3
- package/dist/components/mux-preview/mux-preview.mjs +0 -29
- package/dist/components/mux-preview/mux-preview.mjs.map +0 -1
- package/dist/components/upload-handler/index.d.mts +0 -2
- package/dist/components/upload-handler/index.mjs +0 -3
- package/dist/components/upload-handler/upload-handler.d.mts +0 -22
- package/dist/components/upload-handler/upload-handler.mjs.map +0 -1
- package/dist/components/upload-manager/index.d.mts +0 -2
- package/dist/components/upload-manager/index.mjs +0 -3
- package/dist/components/upload-manager/upload-manager.mjs +0 -273
- package/dist/components/upload-manager/upload-manager.mjs.map +0 -1
- package/dist/endpoints/tusFileExistsHandler.d.mts +0 -11
- package/dist/endpoints/tusFileExistsHandler.mjs.map +0 -1
- package/dist/tus/stores/s3/expiration-manager.mjs.map +0 -1
- package/dist/tus/stores/s3/file-operations.mjs.map +0 -1
- package/dist/tus/stores/s3/metadata-manager.mjs.map +0 -1
- package/dist/tus/stores/s3/parts-manager.mjs.map +0 -1
- package/dist/tus/stores/s3/s3-store.mjs.map +0 -1
- /package/dist/components/{upload-manager/upload-manager.css → uploadManager/uploadManager.css} +0 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/utils/buildThumbnailURL.ts
|
|
2
|
+
function buildThumbnailURL(args) {
|
|
3
|
+
const { storage, s3Store, playbackId, s3Key } = args;
|
|
4
|
+
if (storage === "mux" && playbackId) return `https://image.mux.com/${playbackId}/thumbnail.jpg?width=200&height=200&fit_mode=pad`;
|
|
5
|
+
if (storage === "s3" && s3Key) return `https://wsrv.nl/?url=${s3Store?.getUrl(s3Key)}?width=512&height=512&default=1&q=80`;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
//#endregion
|
|
9
|
+
export { buildThumbnailURL };
|
|
10
|
+
//# sourceMappingURL=buildThumbnailURL.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildThumbnailURL.mjs","names":["S3Store","Storage","BuildThumbnailURLArgs","storage","playbackId","s3Key","s3Store","buildThumbnailURL","args","url","getUrl"],"sources":["../../src/utils/buildThumbnailURL.ts"],"sourcesContent":["import type { S3Store } from '../tus/stores/s3/s3Store'\nimport type { Storage } from '../types'\n\ninterface BuildThumbnailURLArgs {\n storage: Storage\n playbackId?: string\n s3Key?: string\n s3Store?: S3Store | null\n}\n\nexport function buildThumbnailURL(args: BuildThumbnailURLArgs) {\n const { storage, s3Store, playbackId, s3Key } = args\n\n if (storage === 'mux' && playbackId) {\n return `https://image.mux.com/${playbackId}/thumbnail.jpg?width=200&height=200&fit_mode=pad`\n }\n\n if (storage === 's3' && s3Key) {\n const url = s3Store?.getUrl(s3Key)\n return `https://wsrv.nl/?url=${url}?width=512&height=512&default=1&q=80`\n }\n}\n"],"mappings":";AAUA,SAAgBO,kBAAkBC,MAA6B;CAC7D,MAAM,EAAEL,SAASG,SAASF,YAAYC,UAAUG;AAEhD,KAAIL,YAAY,SAASC,WACvB,QAAO,yBAAyBA,WAAU;AAG5C,KAAID,YAAY,QAAQE,MAEtB,QAAO,wBADKC,SAASI,OAAOL,MAAM,CACA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { MediaCloudDefaultPluginOptions } from "../types/index.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/utils/defaultOptions.d.ts
|
|
4
|
+
declare const defaultOptions: MediaCloudDefaultPluginOptions;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { defaultOptions };
|
|
7
|
+
//# sourceMappingURL=defaultOptions.d.mts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/utils/defaultOptions.ts
|
|
2
|
+
const defaultOptions = {
|
|
3
|
+
enabled: true,
|
|
4
|
+
collection: "media",
|
|
5
|
+
view: "grid",
|
|
6
|
+
folders: true,
|
|
7
|
+
storage: { "video/*": "mux" }
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
//#endregion
|
|
11
|
+
export { defaultOptions };
|
|
12
|
+
//# sourceMappingURL=defaultOptions.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaultOptions.mjs","names":["MediaCloudDefaultPluginOptions","defaultOptions","enabled","collection","view","folders","storage"],"sources":["../../src/utils/defaultOptions.ts"],"sourcesContent":["import { MediaCloudDefaultPluginOptions } from '../types'\n\nexport const defaultOptions: MediaCloudDefaultPluginOptions = {\n enabled: true,\n collection: 'media',\n view: 'grid',\n folders: true,\n storage: {\n 'video/*': 'mux',\n },\n}\n"],"mappings":";AAEA,MAAaC,iBAAiD;CAC5DC,SAAS;CACTC,YAAY;CACZC,MAAM;CACNC,SAAS;CACTC,SAAS,EACP,WAAW,OACb;CACD"}
|
package/dist/utils/file.d.mts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
import { MediaCloudPluginOptions, MimeType } from "../types/index.mjs";
|
|
2
|
+
import { S3Store } from "../tus/stores/s3/s3Store.mjs";
|
|
3
|
+
import * as payload0 from "payload";
|
|
4
|
+
|
|
1
5
|
//#region src/utils/file.d.ts
|
|
6
|
+
|
|
2
7
|
/**
|
|
3
8
|
* Checks if a file is a video file supported by Mux
|
|
4
9
|
* @param file - The file to check
|
|
@@ -10,7 +15,7 @@ declare function isVideo(file: File): Promise<boolean>;
|
|
|
10
15
|
* @param file - The file to check
|
|
11
16
|
* @returns Promise that resolves to the MIME type of the file or undefined if it cannot be determined
|
|
12
17
|
*/
|
|
13
|
-
declare function
|
|
18
|
+
declare function getMimeType(file: File): Promise<MimeType | undefined>;
|
|
14
19
|
/**
|
|
15
20
|
* Generates a unique filename by appending a random suffix if needed
|
|
16
21
|
* @param originalFilename - The original filename
|
|
@@ -25,6 +30,15 @@ declare function generateUniqueFilename(originalFilename: string): string;
|
|
|
25
30
|
* @throws {TypeError} When filename is not a string
|
|
26
31
|
*/
|
|
27
32
|
declare function sanitizeFilename(filename: string): string;
|
|
33
|
+
interface CreateFileEndpointsArgs {
|
|
34
|
+
getS3Store: () => S3Store;
|
|
35
|
+
pluginOptions: MediaCloudPluginOptions;
|
|
36
|
+
}
|
|
37
|
+
declare function createFileEndpoints(args: CreateFileEndpointsArgs): {
|
|
38
|
+
handler: payload0.PayloadHandler;
|
|
39
|
+
method: "get";
|
|
40
|
+
path: string;
|
|
41
|
+
}[];
|
|
28
42
|
//#endregion
|
|
29
|
-
export { generateUniqueFilename,
|
|
43
|
+
export { createFileEndpoints, generateUniqueFilename, getMimeType, isVideo, sanitizeFilename };
|
|
30
44
|
//# sourceMappingURL=file.d.mts.map
|
package/dist/utils/file.mjs
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { MediaCloudErrors } from "../types/errors.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { useMagicError } from "../error-handler/dist/index.mjs";
|
|
3
|
+
import { getFileExistsHandler } from "../endpoints/fileExistsHandler.mjs";
|
|
3
4
|
import { fileTypeFromBuffer } from "file-type";
|
|
4
5
|
import { parse } from "pathe";
|
|
5
6
|
|
|
6
7
|
//#region src/utils/file.ts
|
|
7
|
-
const {
|
|
8
|
+
const magicError = useMagicError({ prefix: "PLUGIN-MEDIA-CLOUD" });
|
|
9
|
+
const { logError, throwError } = magicError;
|
|
8
10
|
const MUX_SUPPORTED_VIDEO_FORMATS = new Set([
|
|
9
11
|
"application/mxf",
|
|
10
12
|
"video/3gpp",
|
|
@@ -35,14 +37,51 @@ async function isVideo(file) {
|
|
|
35
37
|
return false;
|
|
36
38
|
}
|
|
37
39
|
}
|
|
40
|
+
const allowedMimeTypes = new Set([
|
|
41
|
+
"application/mxf",
|
|
42
|
+
"video/3gpp",
|
|
43
|
+
"video/3gpp2",
|
|
44
|
+
"video/mp2t",
|
|
45
|
+
"video/mp4",
|
|
46
|
+
"video/mpeg",
|
|
47
|
+
"video/quicktime",
|
|
48
|
+
"video/webm",
|
|
49
|
+
"video/x-f4v",
|
|
50
|
+
"video/x-flv",
|
|
51
|
+
"video/x-matroska",
|
|
52
|
+
"video/x-ms-asf",
|
|
53
|
+
"video/x-ms-wmv",
|
|
54
|
+
"video/x-msvideo",
|
|
55
|
+
"video/x-mxf",
|
|
56
|
+
"image/apng",
|
|
57
|
+
"image/avif",
|
|
58
|
+
"image/gif",
|
|
59
|
+
"image/jpeg",
|
|
60
|
+
"image/png",
|
|
61
|
+
"image/svg+xml",
|
|
62
|
+
"image/webp"
|
|
63
|
+
]);
|
|
64
|
+
/**
|
|
65
|
+
* Check the mime type against allowed mime types
|
|
66
|
+
* @param mimeType - The file to check
|
|
67
|
+
*/
|
|
68
|
+
function validateMimeType(mimeType) {
|
|
69
|
+
if (!allowedMimeTypes.has(mimeType)) throwError(MediaCloudErrors.FILE_TYPE_UNSUPPORTED_ERROR);
|
|
70
|
+
}
|
|
38
71
|
/**
|
|
39
72
|
* Gets the MIME type of a file using file-type library
|
|
40
73
|
* @param file - The file to check
|
|
41
74
|
* @returns Promise that resolves to the MIME type of the file or undefined if it cannot be determined
|
|
42
75
|
*/
|
|
43
|
-
async function
|
|
76
|
+
async function getMimeType(file) {
|
|
44
77
|
try {
|
|
45
|
-
|
|
78
|
+
const fileType = await fileTypeFromBuffer(new Uint8Array(await file.arrayBuffer()));
|
|
79
|
+
if (!fileType?.mime) {
|
|
80
|
+
logError(MediaCloudErrors.FILE_TYPE_ERROR.message);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
validateMimeType(fileType.mime);
|
|
84
|
+
return fileType.mime;
|
|
46
85
|
} catch (_error) {
|
|
47
86
|
logError(MediaCloudErrors.FILE_TYPE_ERROR.message);
|
|
48
87
|
return;
|
|
@@ -56,7 +95,7 @@ async function getFileType(file) {
|
|
|
56
95
|
function generateUniqueFilename(originalFilename) {
|
|
57
96
|
const timestamp = Date.now().toString(36);
|
|
58
97
|
const { name, ext } = parse(originalFilename);
|
|
59
|
-
return `${name}-${timestamp}${ext}`;
|
|
98
|
+
return `${sanitizeFilename(name)}-${timestamp}${ext}`;
|
|
60
99
|
}
|
|
61
100
|
/**
|
|
62
101
|
* Sanitizes a filename by removing/replacing invalid characters and handling edge cases
|
|
@@ -74,7 +113,20 @@ function sanitizeFilename(filename) {
|
|
|
74
113
|
return filename;
|
|
75
114
|
}
|
|
76
115
|
}
|
|
116
|
+
function createFileEndpoints(args) {
|
|
117
|
+
const { getS3Store, pluginOptions } = args;
|
|
118
|
+
const collection = pluginOptions.collection;
|
|
119
|
+
magicError.assert(collection, MediaCloudErrors.COLLECTION_REQUIRED);
|
|
120
|
+
return [{
|
|
121
|
+
handler: getFileExistsHandler({
|
|
122
|
+
getS3Store,
|
|
123
|
+
collection
|
|
124
|
+
}),
|
|
125
|
+
method: "get",
|
|
126
|
+
path: "/uploads/:filename/exists"
|
|
127
|
+
}];
|
|
128
|
+
}
|
|
77
129
|
|
|
78
130
|
//#endregion
|
|
79
|
-
export { generateUniqueFilename,
|
|
131
|
+
export { createFileEndpoints, generateUniqueFilename, getMimeType, isVideo, sanitizeFilename };
|
|
80
132
|
//# sourceMappingURL=file.mjs.map
|
package/dist/utils/file.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file.mjs","names":[],"sources":["../../src/utils/file.ts"],"sourcesContent":["import { fileTypeFromBuffer } from 'file-type'\nimport { parse } from 'pathe'\n\nimport {
|
|
1
|
+
{"version":3,"file":"file.mjs","names":["fileTypeFromBuffer","parse","getFileExistsHandler","MediaCloudErrors","MediaCloudPluginOptions","MimeType","useMagicError","UseMagicErrorReturn","S3Store","magicError","prefix","logError","throwError","MUX_SUPPORTED_VIDEO_FORMATS","Set","isVideo","file","File","Promise","buffer","Uint8Array","arrayBuffer","fileType","mime","has","allowedMimeTypes","validateMimeType","mimeType","FILE_TYPE_UNSUPPORTED_ERROR","getMimeType","FILE_TYPE_ERROR","message","undefined","_error","generateUniqueFilename","originalFilename","timestamp","Date","now","toString","name","ext","sanitizedName","sanitizeFilename","filename","parsed","sanitized","replace","FILENAME_SANITIZE_ERROR","CreateFileEndpointsArgs","getS3Store","pluginOptions","createFileEndpoints","args","collection","assert","COLLECTION_REQUIRED","handler","method","const","path"],"sources":["../../src/utils/file.ts"],"sourcesContent":["import { fileTypeFromBuffer } from 'file-type'\nimport { parse } from 'pathe'\n\nimport { getFileExistsHandler } from '../endpoints/fileExistsHandler'\nimport { MediaCloudErrors } from '../types/errors'\n\nimport { MediaCloudPluginOptions, MimeType } from '../types'\nimport { useMagicError, type UseMagicErrorReturn } from '@maas/error-handler'\n\nimport type { S3Store } from '../tus/stores/s3/s3Store'\n\nconst magicError: UseMagicErrorReturn = useMagicError({\n prefix: 'PLUGIN-MEDIA-CLOUD',\n})\n\nconst { logError, throwError } = magicError\n\nconst MUX_SUPPORTED_VIDEO_FORMATS = new Set([\n 'application/mxf',\n 'video/3gpp',\n 'video/3gpp2',\n 'video/mp2t',\n 'video/mp4',\n 'video/mpeg',\n 'video/quicktime',\n 'video/webm',\n 'video/x-f4v',\n 'video/x-flv',\n 'video/x-matroska',\n 'video/x-ms-asf',\n 'video/x-ms-wmv',\n 'video/x-msvideo',\n 'video/x-mxf',\n])\n\n/**\n * Checks if a file is a video file supported by Mux\n * @param file - The file to check\n * @returns Promise that resolves to true if the file is a supported video format, false otherwise\n */\nexport async function isVideo(file: File): Promise<boolean> {\n try {\n const buffer = new Uint8Array(await file.arrayBuffer())\n const fileType = await fileTypeFromBuffer(buffer)\n\n return fileType?.mime\n ? MUX_SUPPORTED_VIDEO_FORMATS.has(fileType.mime)\n : false\n } catch {\n return false\n }\n}\n\nconst allowedMimeTypes = new Set<MimeType>([\n 'application/mxf',\n 'video/3gpp',\n 'video/3gpp2',\n 'video/mp2t',\n 'video/mp4',\n 'video/mpeg',\n 'video/quicktime',\n 'video/webm',\n 'video/x-f4v',\n 'video/x-flv',\n 'video/x-matroska',\n 'video/x-ms-asf',\n 'video/x-ms-wmv',\n 'video/x-msvideo',\n 'video/x-mxf',\n 'image/apng',\n 'image/avif',\n 'image/gif',\n 'image/jpeg',\n 'image/png',\n 'image/svg+xml',\n 'image/webp',\n])\n\n/**\n * Check the mime type against allowed mime types\n * @param mimeType - The file to check\n */\nfunction validateMimeType(mimeType: string) {\n if (!allowedMimeTypes.has(mimeType as MimeType)) {\n throwError(MediaCloudErrors.FILE_TYPE_UNSUPPORTED_ERROR)\n }\n}\n\n/**\n * Gets the MIME type of a file using file-type library\n * @param file - The file to check\n * @returns Promise that resolves to the MIME type of the file or undefined if it cannot be determined\n */\nexport async function getMimeType(file: File): Promise<MimeType | undefined> {\n try {\n const buffer = new Uint8Array(await file.arrayBuffer())\n const fileType = await fileTypeFromBuffer(buffer)\n\n if (!fileType?.mime) {\n logError(MediaCloudErrors.FILE_TYPE_ERROR.message)\n return undefined\n }\n\n validateMimeType(fileType.mime)\n return fileType.mime as MimeType\n } catch (_error) {\n logError(MediaCloudErrors.FILE_TYPE_ERROR.message)\n return undefined\n }\n}\n\n/**\n * Generates a unique filename by appending a random suffix if needed\n * @param originalFilename - The original filename\n * @returns A unique filename with a random suffix appended before the extension\n */\nexport function generateUniqueFilename(originalFilename: string): string {\n const timestamp = Date.now().toString(36)\n // Parse name and extension\n const { name, ext } = parse(originalFilename)\n\n // Sanitize name\n const sanitizedName = sanitizeFilename(name)\n\n return `${sanitizedName}-${timestamp}${ext}`\n}\n\n/**\n * Sanitizes a filename by removing/replacing invalid characters and handling edge cases\n * Converts all non-alphanumeric characters (except dots for extensions) to underscores\n * @param filename - The filename to sanitize\n * @returns A sanitized filename safe for all operating systems\n * @throws {TypeError} When filename is not a string\n */\nexport function sanitizeFilename(filename: string): string {\n try {\n const parsed = parse(filename)\n const sanitized = parsed.name\n .replace(/[^a-zA-Z0-9_.-]/g, '_')\n .replace(/_{2,}/g, '_')\n .replace(/^_|_$/g, '')\n return `${sanitized}${parsed.ext}`\n } catch (_error) {\n logError(MediaCloudErrors.FILENAME_SANITIZE_ERROR.message)\n return filename\n }\n}\n\ninterface CreateFileEndpointsArgs {\n getS3Store: () => S3Store\n pluginOptions: MediaCloudPluginOptions\n}\n\nexport function createFileEndpoints(args: CreateFileEndpointsArgs) {\n const { getS3Store, pluginOptions } = args\n const collection = pluginOptions.collection\n\n magicError.assert(collection, MediaCloudErrors.COLLECTION_REQUIRED)\n\n return [\n {\n handler: getFileExistsHandler({ getS3Store, collection }),\n method: 'get' as const,\n path: '/uploads/:filename/exists',\n },\n ]\n}\n"],"mappings":";;;;;;;AAWA,MAAMS,aAAkCH,cAAc,EACpDI,QAAQ,sBACT,CAAC;AAEF,MAAM,EAAEC,UAAUC,eAAeH;AAEjC,MAAMI,8BAA8B,IAAIC,IAAI;CAC1C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;;AAOF,eAAsBC,QAAQC,MAA8B;AAC1D,KAAI;EAEF,MAAMM,WAAW,MAAMtB,mBADR,IAAIoB,WAAW,MAAMJ,KAAKK,aAAa,CAAC,CACN;AAEjD,SAAOC,UAAUC,OACbV,4BAA4BW,IAAIF,SAASC,KAAK,GAC9C;SACE;AACN,SAAO;;;AAIX,MAAME,mBAAmB,IAAIX,IAAc;CACzC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;AAMF,SAASY,iBAAiBC,UAAkB;AAC1C,KAAI,CAACF,iBAAiBD,IAAIG,SAAqB,CAC7Cf,YAAWT,iBAAiByB,4BAA4B;;;;;;;AAS5D,eAAsBC,YAAYb,MAA2C;AAC3E,KAAI;EAEF,MAAMM,WAAW,MAAMtB,mBADR,IAAIoB,WAAW,MAAMJ,KAAKK,aAAa,CAAC,CACN;AAEjD,MAAI,CAACC,UAAUC,MAAM;AACnBZ,YAASR,iBAAiB2B,gBAAgBC,QAAQ;AAClD;;AAGFL,mBAAiBJ,SAASC,KAAK;AAC/B,SAAOD,SAASC;UACTU,QAAQ;AACftB,WAASR,iBAAiB2B,gBAAgBC,QAAQ;AAClD;;;;;;;;AASJ,SAAgBG,uBAAuBC,kBAAkC;CACvE,MAAMC,YAAYC,KAAKC,KAAK,CAACC,SAAS,GAAG;CAEzC,MAAM,EAAEC,MAAMC,QAAQxC,MAAMkC,iBAAiB;AAK7C,QAAO,GAFeQ,iBAAiBH,KAAK,CAErB,GAAIJ,YAAYK;;;;;;;;;AAUzC,SAAgBE,iBAAiBC,UAA0B;AACzD,KAAI;EACF,MAAMC,SAAS5C,MAAM2C,SAAS;AAK9B,SAAO,GAJWC,OAAOL,KACtBO,QAAQ,oBAAoB,IAAI,CAChCA,QAAQ,UAAU,IAAI,CACtBA,QAAQ,UAAU,GAAG,GACFF,OAAOJ;UACtBR,QAAQ;AACftB,WAASR,iBAAiB6C,wBAAwBjB,QAAQ;AAC1D,SAAOa;;;AASX,SAAgBQ,oBAAoBC,MAA+B;CACjE,MAAM,EAAEH,YAAYC,kBAAkBE;CACtC,MAAMC,aAAaH,cAAcG;AAEjC7C,YAAW8C,OAAOD,YAAYnD,iBAAiBqD,oBAAoB;AAEnE,QAAO,CACL;EACEC,SAASvD,qBAAqB;GAAEgD;GAAYI;GAAY,CAAC;EACzDI,QAAQ;EACRE,MAAM;EACP,CACF"}
|
package/dist/utils/mux.mjs
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import { MediaCloudErrors } from "../types/errors.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { useMagicError } from "../error-handler/dist/index.mjs";
|
|
3
3
|
import { getMuxAssetHandler } from "../endpoints/muxAssetHandler.mjs";
|
|
4
4
|
import { getMuxCreateUploadHandler } from "../endpoints/muxCreateUploadHandler.mjs";
|
|
5
5
|
import { getMuxWebhookHandler } from "../endpoints/muxWebhookHandler.mjs";
|
|
6
6
|
import Mux from "@mux/mux-node";
|
|
7
7
|
|
|
8
8
|
//#region src/utils/mux.ts
|
|
9
|
-
const {
|
|
9
|
+
const magicError = useMagicError({ prefix: "PLUGIN-MEDIA-CLOUD" });
|
|
10
10
|
function createMuxEndpoints(args) {
|
|
11
11
|
const { getMuxClient, pluginOptions } = args;
|
|
12
|
+
const collection = pluginOptions.collection;
|
|
13
|
+
magicError.assert(collection, MediaCloudErrors.COLLECTION_REQUIRED);
|
|
12
14
|
return [
|
|
13
15
|
{
|
|
14
|
-
handler: getMuxWebhookHandler({
|
|
16
|
+
handler: getMuxWebhookHandler({
|
|
17
|
+
getMuxClient,
|
|
18
|
+
collection
|
|
19
|
+
}),
|
|
15
20
|
method: "post",
|
|
16
21
|
path: "/mux/webhook"
|
|
17
22
|
},
|
|
@@ -24,7 +29,10 @@ function createMuxEndpoints(args) {
|
|
|
24
29
|
path: "/mux/upload"
|
|
25
30
|
},
|
|
26
31
|
{
|
|
27
|
-
handler: getMuxAssetHandler({
|
|
32
|
+
handler: getMuxAssetHandler({
|
|
33
|
+
getMuxClient,
|
|
34
|
+
collection
|
|
35
|
+
}),
|
|
28
36
|
method: "get",
|
|
29
37
|
path: "/mux/asset"
|
|
30
38
|
}
|
|
@@ -36,7 +44,9 @@ function createMuxEndpoints(args) {
|
|
|
36
44
|
* @throws {Error} When required Mux configuration is missing
|
|
37
45
|
*/
|
|
38
46
|
function validateMuxConfig(muxConfig) {
|
|
39
|
-
|
|
47
|
+
magicError.assert(muxConfig, MediaCloudErrors.MUX_CONFIG_INCOMPLETE);
|
|
48
|
+
magicError.assert(muxConfig?.tokenId, MediaCloudErrors.MUX_CONFIG_MISSING);
|
|
49
|
+
magicError.assert(muxConfig?.tokenSecret, MediaCloudErrors.MUX_CONFIG_MISSING);
|
|
40
50
|
}
|
|
41
51
|
/**
|
|
42
52
|
* Creates a new Mux client instance
|
|
@@ -44,10 +54,11 @@ function validateMuxConfig(muxConfig) {
|
|
|
44
54
|
* @returns A configured Mux client
|
|
45
55
|
*/
|
|
46
56
|
function createMuxClient(muxConfig) {
|
|
57
|
+
validateMuxConfig(muxConfig);
|
|
47
58
|
return new Mux({
|
|
48
|
-
tokenId: muxConfig
|
|
49
|
-
tokenSecret: muxConfig
|
|
50
|
-
webhookSecret: muxConfig
|
|
59
|
+
tokenId: muxConfig?.tokenId,
|
|
60
|
+
tokenSecret: muxConfig?.tokenSecret,
|
|
61
|
+
webhookSecret: muxConfig?.webhookSecret
|
|
51
62
|
});
|
|
52
63
|
}
|
|
53
64
|
|
package/dist/utils/mux.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mux.mjs","names":[],"sources":["../../src/utils/mux.ts"],"sourcesContent":["import Mux from '@mux/mux-node'\n\nimport { MediaCloudErrors } from '../types/errors'\nimport {
|
|
1
|
+
{"version":3,"file":"mux.mjs","names":["Mux","MediaCloudErrors","getMuxAssetHandler","getMuxCreateUploadHandler","getMuxWebhookHandler","useMagicError","MediaCloudPluginOptions","UseMagicErrorReturn","magicError","prefix","CreateMuxEndpointsArgs","getMuxClient","pluginOptions","createMuxEndpoints","args","collection","assert","COLLECTION_REQUIRED","handler","method","const","path","validateMuxConfig","muxConfig","MUX_CONFIG_INCOMPLETE","tokenId","MUX_CONFIG_MISSING","tokenSecret","createMuxClient","webhookSecret"],"sources":["../../src/utils/mux.ts"],"sourcesContent":["import Mux from '@mux/mux-node'\n\nimport { MediaCloudErrors } from '../types/errors'\nimport { getMuxAssetHandler } from '../endpoints/muxAssetHandler'\nimport { getMuxCreateUploadHandler } from '../endpoints/muxCreateUploadHandler'\nimport { getMuxWebhookHandler } from '../endpoints/muxWebhookHandler'\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 * Creates Mux-related endpoints for asset handling\n * @param args - The arguments for creating Mux endpoints\n * @returns An array of Mux endpoint configurations\n */\ninterface CreateMuxEndpointsArgs {\n getMuxClient: () => Mux\n pluginOptions: MediaCloudPluginOptions\n}\n\nexport function createMuxEndpoints(args: CreateMuxEndpointsArgs) {\n const { getMuxClient, pluginOptions } = args\n\n const collection = pluginOptions.collection\n\n magicError.assert(collection, MediaCloudErrors.COLLECTION_REQUIRED)\n\n return [\n {\n handler: getMuxWebhookHandler({ getMuxClient, collection }),\n method: 'post' as const,\n path: '/mux/webhook',\n },\n {\n handler: getMuxCreateUploadHandler({ getMuxClient, pluginOptions }),\n method: 'post' as const,\n path: '/mux/upload',\n },\n {\n handler: getMuxAssetHandler({ getMuxClient, collection }),\n method: 'get' as const,\n path: '/mux/asset',\n },\n ]\n}\n\n/**\n * Validates Mux configuration options\n * @param muxConfig - The Mux configuration to validate\n * @throws {Error} When required Mux configuration is missing\n */\nexport function validateMuxConfig(\n muxConfig: MediaCloudPluginOptions['mux']\n): void {\n magicError.assert(muxConfig, MediaCloudErrors.MUX_CONFIG_INCOMPLETE)\n magicError.assert(muxConfig?.tokenId, MediaCloudErrors.MUX_CONFIG_MISSING)\n magicError.assert(muxConfig?.tokenSecret, MediaCloudErrors.MUX_CONFIG_MISSING)\n}\n\n/**\n * Creates a new Mux client instance\n * @param muxConfig - The Mux configuration options\n * @returns A configured Mux client\n */\nexport function createMuxClient(\n muxConfig: MediaCloudPluginOptions['mux']\n): Mux {\n validateMuxConfig(muxConfig)\n\n return new Mux({\n tokenId: muxConfig?.tokenId,\n tokenSecret: muxConfig?.tokenSecret,\n webhookSecret: muxConfig?.webhookSecret,\n })\n}\n"],"mappings":";;;;;;;;AAWA,MAAMQ,aAAkCH,cAAc,EACpDI,QAAQ,sBACT,CAAC;AAYF,SAAgBI,mBAAmBC,MAA8B;CAC/D,MAAM,EAAEH,cAAcC,kBAAkBE;CAExC,MAAMC,aAAaH,cAAcG;AAEjCP,YAAWQ,OAAOD,YAAYd,iBAAiBgB,oBAAoB;AAEnE,QAAO;EACL;GACEC,SAASd,qBAAqB;IAAEO;IAAcI;IAAY,CAAC;GAC3DI,QAAQ;GACRE,MAAM;GACP;EACD;GACEH,SAASf,0BAA0B;IAAEQ;IAAcC;IAAe,CAAC;GACnEO,QAAQ;GACRE,MAAM;GACP;EACD;GACEH,SAAShB,mBAAmB;IAAES;IAAcI;IAAY,CAAC;GACzDI,QAAQ;GACRE,MAAM;GACP;EACF;;;;;;;AAQH,SAAgBC,kBACdC,WACM;AACNf,YAAWQ,OAAOO,WAAWtB,iBAAiBuB,sBAAsB;AACpEhB,YAAWQ,OAAOO,WAAWE,SAASxB,iBAAiByB,mBAAmB;AAC1ElB,YAAWQ,OAAOO,WAAWI,aAAa1B,iBAAiByB,mBAAmB;;;;;;;AAQhF,SAAgBE,gBACdL,WACK;AACLD,mBAAkBC,UAAU;AAE5B,QAAO,IAAIvB,IAAI;EACbyB,SAASF,WAAWE;EACpBE,aAAaJ,WAAWI;EACxBE,eAAeN,WAAWM;EAC3B,CAAC"}
|
package/dist/utils/tus.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MediaCloudPluginOptions } from "../types/index.mjs";
|
|
2
|
-
import { S3Store } from "../tus/stores/s3/
|
|
2
|
+
import { S3Store } from "../tus/stores/s3/s3Store.mjs";
|
|
3
3
|
import { Server } from "@tus/server";
|
|
4
4
|
import * as payload0 from "payload";
|
|
5
5
|
import { PayloadRequest } from "payload";
|
|
@@ -8,22 +8,25 @@ import { PayloadRequest } from "payload";
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Creates a TUS server instance with S3 storage
|
|
11
|
-
* @param args -
|
|
11
|
+
* @param args.getS3Store - Function that returns an S3 client instance
|
|
12
|
+
* @param args.pluginOptions - Media cloud plugin options
|
|
12
13
|
* @returns A configured TusServer instance
|
|
13
14
|
*/
|
|
14
15
|
interface CreateTusServerArgs {
|
|
15
|
-
|
|
16
|
+
getS3Store: () => S3Store;
|
|
16
17
|
pluginOptions: MediaCloudPluginOptions;
|
|
17
18
|
}
|
|
18
19
|
declare function createTusServer(args: CreateTusServerArgs): Server;
|
|
19
20
|
/**
|
|
20
21
|
* Creates TUS upload endpoints for file handling
|
|
21
|
-
* @param
|
|
22
|
+
* @param args.getTusServer - Function that returns a TUS server instance
|
|
23
|
+
* @param args.getS3Store - Function that returns an S3 client instance
|
|
22
24
|
* @returns An array of endpoint configurations
|
|
23
25
|
*/
|
|
24
26
|
interface CreateTusEndpointsArgs {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
getTusServer: () => Server;
|
|
28
|
+
getS3Store: () => S3Store;
|
|
29
|
+
pluginOptions: MediaCloudPluginOptions;
|
|
27
30
|
}
|
|
28
31
|
declare function createTusEndpoints(args: CreateTusEndpointsArgs): ({
|
|
29
32
|
handler: (req: PayloadRequest) => Promise<Response>;
|
package/dist/utils/tus.mjs
CHANGED
|
@@ -1,30 +1,41 @@
|
|
|
1
|
+
import { MediaCloudErrors } from "../types/errors.mjs";
|
|
2
|
+
import { useMagicError } from "../error-handler/dist/index.mjs";
|
|
1
3
|
import { generateUniqueFilename } from "./file.mjs";
|
|
2
4
|
import { getTusPostProcessorHandler } from "../endpoints/tusPostProcessorHandler.mjs";
|
|
3
|
-
import {
|
|
5
|
+
import { getTusFolderHandler } from "../endpoints/tusFolderHandler.mjs";
|
|
4
6
|
import { getTusCleanupHandler } from "../endpoints/tusCleanupHandler.mjs";
|
|
5
7
|
import { Server } from "@tus/server";
|
|
6
8
|
|
|
7
9
|
//#region src/utils/tus.ts
|
|
10
|
+
const magicError = useMagicError({ prefix: "PLUGIN-MEDIA-CLOUD" });
|
|
8
11
|
function createTusServer(args) {
|
|
9
|
-
const {
|
|
12
|
+
const { getS3Store, pluginOptions } = args;
|
|
13
|
+
const s3Store = getS3Store();
|
|
10
14
|
return new Server({
|
|
11
15
|
datastore: s3Store,
|
|
16
|
+
path: "/api/uploads",
|
|
17
|
+
respectForwardedHeaders: pluginOptions.s3?.respectForwardedHeaders ?? true,
|
|
12
18
|
namingFunction: async (_req, metadata) => {
|
|
13
19
|
return metadata?.filename ?? generateUniqueFilename("");
|
|
14
20
|
},
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
onUploadFinish: async (_req, upload) => {
|
|
22
|
+
const filename = upload.metadata?.filename ?? "";
|
|
23
|
+
await s3Store.cleanup(filename);
|
|
24
|
+
return Promise.resolve({});
|
|
25
|
+
}
|
|
17
26
|
});
|
|
18
27
|
}
|
|
19
28
|
function createTusEndpoints(args) {
|
|
20
|
-
const {
|
|
29
|
+
const { getTusServer, getS3Store, pluginOptions } = args;
|
|
30
|
+
const collection = pluginOptions.collection;
|
|
31
|
+
magicError.assert(collection, MediaCloudErrors.COLLECTION_REQUIRED);
|
|
21
32
|
/**
|
|
22
33
|
* Handles TUS requests through the server
|
|
23
34
|
* @param req - The payload request object
|
|
24
35
|
* @returns The server response
|
|
25
36
|
*/
|
|
26
37
|
function tusHandler(req) {
|
|
27
|
-
return
|
|
38
|
+
return getTusServer().handleWeb(req);
|
|
28
39
|
}
|
|
29
40
|
return [
|
|
30
41
|
{
|
|
@@ -58,17 +69,26 @@ function createTusEndpoints(args) {
|
|
|
58
69
|
path: "/uploads/:id"
|
|
59
70
|
},
|
|
60
71
|
{
|
|
61
|
-
handler:
|
|
72
|
+
handler: getTusPostProcessorHandler({
|
|
73
|
+
getS3Store,
|
|
74
|
+
collection
|
|
75
|
+
}),
|
|
62
76
|
method: "get",
|
|
63
|
-
path: "/uploads/:filename/
|
|
77
|
+
path: "/uploads/:filename/process"
|
|
64
78
|
},
|
|
65
79
|
{
|
|
66
|
-
handler:
|
|
80
|
+
handler: getTusFolderHandler({
|
|
81
|
+
getS3Store,
|
|
82
|
+
collection
|
|
83
|
+
}),
|
|
67
84
|
method: "get",
|
|
68
|
-
path: "/uploads/:filename/
|
|
85
|
+
path: "/uploads/:filename/folder"
|
|
69
86
|
},
|
|
70
87
|
{
|
|
71
|
-
handler: getTusCleanupHandler({
|
|
88
|
+
handler: getTusCleanupHandler({
|
|
89
|
+
getS3Store,
|
|
90
|
+
collection
|
|
91
|
+
}),
|
|
72
92
|
method: "post",
|
|
73
93
|
path: "/uploads/cleanup"
|
|
74
94
|
}
|
package/dist/utils/tus.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tus.mjs","names":["TusServer"],"sources":["../../src/utils/tus.ts"],"sourcesContent":["import { Server as TusServer } from '@tus/server'\n\nimport { getTusPostProcessorHandler } from '../endpoints/tusPostProcessorHandler'\nimport {
|
|
1
|
+
{"version":3,"file":"tus.mjs","names":["Server","TusServer","getTusPostProcessorHandler","getTusFolderHandler","getTusCleanupHandler","generateUniqueFilename","useMagicError","UseMagicErrorReturn","S3Store","PayloadRequest","MediaCloudPluginOptions","MediaCloudErrors","magicError","prefix","CreateTusServerArgs","getS3Store","pluginOptions","createTusServer","args","s3Store","datastore","path","respectForwardedHeaders","s3","namingFunction","_req","metadata","filename","onUploadFinish","upload","cleanup","Promise","resolve","CreateTusEndpointsArgs","getTusServer","createTusEndpoints","collection","assert","COLLECTION_REQUIRED","tusHandler","req","handleWeb","Request","handler","method","const"],"sources":["../../src/utils/tus.ts"],"sourcesContent":["import { Server as TusServer } from '@tus/server'\n\nimport { getTusPostProcessorHandler } from '../endpoints/tusPostProcessorHandler'\nimport { getTusFolderHandler } from '../endpoints/tusFolderHandler'\nimport { getTusCleanupHandler } from '../endpoints/tusCleanupHandler'\n\nimport { generateUniqueFilename } from './file'\nimport { useMagicError, type UseMagicErrorReturn } from '@maas/error-handler'\n\nimport type { S3Store } from '../tus/stores/s3/s3Store'\nimport type { PayloadRequest } from 'payload'\nimport type { MediaCloudPluginOptions } from '../types'\nimport { MediaCloudErrors } from '../types/errors'\n\nconst magicError: UseMagicErrorReturn = useMagicError({\n prefix: 'PLUGIN-MEDIA-CLOUD',\n})\n\n/**\n * Creates a TUS server instance with S3 storage\n * @param args.getS3Store - Function that returns an S3 client instance\n * @param args.pluginOptions - Media cloud plugin options\n * @returns A configured TusServer instance\n */\ninterface CreateTusServerArgs {\n getS3Store: () => S3Store\n pluginOptions: MediaCloudPluginOptions\n}\n\nexport function createTusServer(args: CreateTusServerArgs): TusServer {\n const { getS3Store, pluginOptions } = args\n\n const s3Store = getS3Store()\n\n return new TusServer({\n datastore: s3Store,\n path: '/api/uploads',\n respectForwardedHeaders: pluginOptions.s3?.respectForwardedHeaders ?? true,\n namingFunction: async (_req, metadata) => {\n return metadata?.filename ?? generateUniqueFilename('')\n },\n onUploadFinish: async (_req, upload) => {\n // Clean up .part and .info files\n const filename = upload.metadata?.filename ?? ''\n await s3Store.cleanup(filename)\n\n // Prevent type error\n return Promise.resolve({})\n },\n })\n}\n\n/**\n * Creates TUS upload endpoints for file handling\n * @param args.getTusServer - Function that returns a TUS server instance\n * @param args.getS3Store - Function that returns an S3 client instance\n * @returns An array of endpoint configurations\n */\ninterface CreateTusEndpointsArgs {\n getTusServer: () => TusServer\n getS3Store: () => S3Store\n pluginOptions: MediaCloudPluginOptions\n}\n\nexport function createTusEndpoints(args: CreateTusEndpointsArgs) {\n const { getTusServer, getS3Store, pluginOptions } = args\n const collection = pluginOptions.collection\n\n magicError.assert(collection, MediaCloudErrors.COLLECTION_REQUIRED)\n\n /**\n * Handles TUS requests through the server\n * @param req - The payload request object\n * @returns The server response\n */\n function tusHandler(req: PayloadRequest) {\n return getTusServer().handleWeb(req as Request)\n }\n\n return [\n { handler: tusHandler, method: 'options' as const, path: '/uploads' },\n { handler: tusHandler, method: 'post' as const, path: '/uploads' },\n { handler: tusHandler, method: 'get' as const, path: '/uploads/:id' },\n { handler: tusHandler, method: 'put' as const, path: '/uploads/:id' },\n { handler: tusHandler, method: 'patch' as const, path: '/uploads/:id' },\n { handler: tusHandler, method: 'delete' as const, path: '/uploads/:id' },\n {\n handler: getTusPostProcessorHandler({ getS3Store, collection }),\n method: 'get' as const,\n path: '/uploads/:filename/process',\n },\n {\n handler: getTusFolderHandler({ getS3Store, collection }),\n method: 'get' as const,\n path: '/uploads/:filename/folder',\n },\n {\n handler: getTusCleanupHandler({ getS3Store, collection }),\n method: 'post' as const,\n path: '/uploads/cleanup',\n },\n ]\n}\n"],"mappings":";;;;;;;;;AAcA,MAAMY,aAAkCN,cAAc,EACpDO,QAAQ,sBACT,CAAC;AAaF,SAAgBI,gBAAgBC,MAAsC;CACpE,MAAM,EAAEH,YAAYC,kBAAkBE;CAEtC,MAAMC,UAAUJ,YAAY;AAE5B,QAAO,IAAId,OAAU;EACnBmB,WAAWD;EACXE,MAAM;EACNC,yBAAyBN,cAAcO,IAAID,2BAA2B;EACtEE,gBAAgB,OAAOC,MAAMC,aAAa;AACxC,UAAOA,UAAUC,YAAYtB,uBAAuB,GAAG;;EAEzDuB,gBAAgB,OAAOH,MAAMI,WAAW;GAEtC,MAAMF,WAAWE,OAAOH,UAAUC,YAAY;AAC9C,SAAMR,QAAQW,QAAQH,SAAS;AAG/B,UAAOI,QAAQC,QAAQ,EAAE,CAAC;;EAE7B,CAAC;;AAeJ,SAAgBG,mBAAmBjB,MAA8B;CAC/D,MAAM,EAAEgB,cAAcnB,YAAYC,kBAAkBE;CACpD,MAAMkB,aAAapB,cAAcoB;AAEjCxB,YAAWyB,OAAOD,YAAYzB,iBAAiB2B,oBAAoB;;;;;;CAOnE,SAASC,WAAWC,KAAqB;AACvC,SAAON,cAAc,CAACO,UAAUD,IAAe;;AAGjD,QAAO;EACL;GAAEG,SAASJ;GAAYK,QAAQ;GAAoBvB,MAAM;GAAY;EACrE;GAAEsB,SAASJ;GAAYK,QAAQ;GAAiBvB,MAAM;GAAY;EAClE;GAAEsB,SAASJ;GAAYK,QAAQ;GAAgBvB,MAAM;GAAgB;EACrE;GAAEsB,SAASJ;GAAYK,QAAQ;GAAgBvB,MAAM;GAAgB;EACrE;GAAEsB,SAASJ;GAAYK,QAAQ;GAAkBvB,MAAM;GAAgB;EACvE;GAAEsB,SAASJ;GAAYK,QAAQ;GAAmBvB,MAAM;GAAgB;EACxE;GACEsB,SAASzC,2BAA2B;IAAEa;IAAYqB;IAAY,CAAC;GAC/DQ,QAAQ;GACRvB,MAAM;GACP;EACD;GACEsB,SAASxC,oBAAoB;IAAEY;IAAYqB;IAAY,CAAC;GACxDQ,QAAQ;GACRvB,MAAM;GACP;EACD;GACEsB,SAASvC,qBAAqB;IAAEW;IAAYqB;IAAY,CAAC;GACzDQ,QAAQ;GACRvB,MAAM;GACP;EACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maas/payload-plugin-media-cloud",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.33",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"contributors": [
|
|
6
6
|
{
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"@mux/upchunk": "^3.5.0",
|
|
41
41
|
"@tus/server": "^2.3.0",
|
|
42
42
|
"@tus/utils": "^0.6.0",
|
|
43
|
+
"defu": "^6.1.4",
|
|
43
44
|
"file-type": "^21.1.1",
|
|
44
45
|
"image-size": "^2.0.2",
|
|
45
46
|
"mitt": "^3.0.1",
|
|
@@ -50,7 +51,9 @@
|
|
|
50
51
|
"peerDependencies": {
|
|
51
52
|
"@mux/mux-player-react": "^3",
|
|
52
53
|
"@payloadcms/plugin-cloud-storage": "^3.61",
|
|
54
|
+
"@payloadcms/translations": "^3.61",
|
|
53
55
|
"@payloadcms/ui": "^3.61",
|
|
56
|
+
"next": "^15.4.10",
|
|
54
57
|
"payload": "^3.61",
|
|
55
58
|
"react": "^19.1",
|
|
56
59
|
"react-dom": "^19.1"
|
|
@@ -65,14 +68,18 @@
|
|
|
65
68
|
},
|
|
66
69
|
"devDependencies": {
|
|
67
70
|
"@mux/mux-player-react": "^3.9.2",
|
|
68
|
-
"@payloadcms/plugin-cloud-storage": "3.
|
|
69
|
-
"@payloadcms/
|
|
71
|
+
"@payloadcms/plugin-cloud-storage": "3.75.0",
|
|
72
|
+
"@payloadcms/translations": "3.75.0",
|
|
73
|
+
"@payloadcms/ui": "3.75.0",
|
|
74
|
+
"@rollup/plugin-babel": "^6.1.0",
|
|
70
75
|
"@types/multistream": "^4.1.3",
|
|
71
76
|
"@types/node": "^22.19.1",
|
|
72
77
|
"@types/react": "19.2.1",
|
|
73
78
|
"@types/react-dom": "19.2.1",
|
|
79
|
+
"babel-plugin-react-compiler": "^1.0.0",
|
|
74
80
|
"glob": "^13.0.0",
|
|
75
|
-
"
|
|
81
|
+
"next": "15.4.8",
|
|
82
|
+
"payload": "3.75.0",
|
|
76
83
|
"react": "19.2.1",
|
|
77
84
|
"react-dom": "19.2.1",
|
|
78
85
|
"tsdown": "^0.16.8",
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { useEffect, useState } from "react";
|
|
4
|
-
import MuxPlayer from "@mux/mux-player-react";
|
|
5
|
-
|
|
6
|
-
//#region src/components/mux-preview/mux-preview.tsx
|
|
7
|
-
/**
|
|
8
|
-
* React component for previewing Mux video assets
|
|
9
|
-
* @param props - The UI field client props containing field data
|
|
10
|
-
* @returns JSX element for Mux video preview
|
|
11
|
-
*/
|
|
12
|
-
function MuxPreview(props) {
|
|
13
|
-
const [playbackId, setPlaybackId] = useState(null);
|
|
14
|
-
const [isClient, setIsClient] = useState(false);
|
|
15
|
-
useEffect(() => {
|
|
16
|
-
setIsClient(true);
|
|
17
|
-
}, []);
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
if (!isClient) return;
|
|
20
|
-
const collection = props.schemaPath?.split(".")[0];
|
|
21
|
-
const docId = window.location.pathname.split("/").pop();
|
|
22
|
-
if (collection && docId && docId !== "create" && docId !== "admin") fetch(`/api/${collection}/${docId}`).then((res) => res.json()).then((data) => setPlaybackId(data.mux?.playbackId || null)).catch(() => setPlaybackId(null));
|
|
23
|
-
}, [props.schemaPath, isClient]);
|
|
24
|
-
return isClient && playbackId ? <MuxPlayer playbackId={playbackId} streamType="on-demand" disableTracking={true} style={{ height: "60vh" }} nohotkeys={true} preload="metadata" /> : null;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
//#endregion
|
|
28
|
-
export { MuxPreview };
|
|
29
|
-
//# sourceMappingURL=mux-preview.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mux-preview.mjs","names":[],"sources":["../../../src/components/mux-preview/mux-preview.tsx"],"sourcesContent":["'use client'\n\nimport { useEffect, useState } from 'react'\nimport MuxPlayer from '@mux/mux-player-react'\n\nimport type React from 'react'\nimport type { UIFieldClientProps } from 'payload'\n\n/**\n * React component for previewing Mux video assets\n * @param props - The UI field client props containing field data\n * @returns JSX element for Mux video preview\n */\nexport function MuxPreview(props: UIFieldClientProps) {\n const [playbackId, setPlaybackId] = useState<string | null>(null)\n const [isClient, setIsClient] = useState(false)\n\n // Ensure we’re on the client side\n useEffect(() => {\n setIsClient(true)\n }, [])\n\n useEffect(() => {\n if (!isClient) {\n return\n }\n\n // Get collection from schemaPath and ID from URL\n const collection = props.schemaPath?.split('.')[0] // \"media.muxPlayer\" -> \"media\"\n const docId = window.location.pathname.split('/').pop() // Get last part of URL\n\n if (collection && docId && docId !== 'create' && docId !== 'admin') {\n fetch(`/api/${collection}/${docId}`)\n .then((res) => res.json())\n .then((data) => setPlaybackId(data.mux?.playbackId || null))\n .catch(() => setPlaybackId(null))\n }\n }, [props.schemaPath, isClient])\n\n // Only render on client with playbackId\n return isClient && playbackId ? (\n <MuxPlayer\n playbackId={playbackId}\n streamType=\"on-demand\"\n disableTracking={true}\n style={{ height: '60vh' }}\n nohotkeys={true}\n preload=\"metadata\"\n />\n ) : null\n}\n"],"mappings":";;;;;;;;;;;AAaA,SAAgB,WAAW,OAA2B;CACpD,MAAM,CAAC,YAAY,iBAAiB,SAAwB,KAAK;CACjE,MAAM,CAAC,UAAU,eAAe,SAAS,MAAM;AAG/C,iBAAgB;AACd,cAAY,KAAK;IAChB,EAAE,CAAC;AAEN,iBAAgB;AACd,MAAI,CAAC,SACH;EAIF,MAAM,aAAa,MAAM,YAAY,MAAM,IAAI,CAAC;EAChD,MAAM,QAAQ,OAAO,SAAS,SAAS,MAAM,IAAI,CAAC,KAAK;AAEvD,MAAI,cAAc,SAAS,UAAU,YAAY,UAAU,QACzD,OAAM,QAAQ,WAAW,GAAG,QAAQ,CACjC,MAAM,QAAQ,IAAI,MAAM,CAAC,CACzB,MAAM,SAAS,cAAc,KAAK,KAAK,cAAc,KAAK,CAAC,CAC3D,YAAY,cAAc,KAAK,CAAC;IAEpC,CAAC,MAAM,YAAY,SAAS,CAAC;AAGhC,QAAO,YAAY,aACjB,CAAC,UACC,YAAY,YACZ,uBACA,iBAAiB,MACjB,OAAO,EAAE,QAAQ,QAAQ,EACzB,WAAW,MACX,wBAEA"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import * as react0 from "react";
|
|
2
|
-
import * as payload1 from "payload";
|
|
3
|
-
|
|
4
|
-
//#region src/components/upload-handler/upload-handler.d.ts
|
|
5
|
-
declare const UploadHandler: ({
|
|
6
|
-
children,
|
|
7
|
-
collectionSlug,
|
|
8
|
-
enabled,
|
|
9
|
-
extra,
|
|
10
|
-
prefix,
|
|
11
|
-
serverHandlerPath
|
|
12
|
-
}: {
|
|
13
|
-
children: react0.ReactNode;
|
|
14
|
-
collectionSlug: payload1.UploadCollectionSlug;
|
|
15
|
-
enabled?: boolean;
|
|
16
|
-
extra: Record<string, unknown>;
|
|
17
|
-
prefix?: string;
|
|
18
|
-
serverHandlerPath: `/${string}`;
|
|
19
|
-
}) => react0.JSX.Element;
|
|
20
|
-
//#endregion
|
|
21
|
-
export { UploadHandler };
|
|
22
|
-
//# sourceMappingURL=upload-handler.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"upload-handler.mjs","names":["uploadArgs: UploadArgs"],"sources":["../../../src/components/upload-handler/upload-handler.tsx"],"sourcesContent":["'use client'\n\nimport * as upchunk from '@mux/upchunk'\nimport * as tus from 'tus-js-client'\n\nimport { toast } from '@payloadcms/ui'\nimport { createClientUploadHandler } from '@payloadcms/plugin-cloud-storage/client'\n\nimport { MediaCloudErrors, MediaCloudLogs } from '../../types/errors'\nimport { useMediaCloudEmitter } from '../../hooks/useMediaCloudEmitter'\nimport { useErrorHandler } from '../../hooks/useErrorHandler'\nimport { isVideo, getFileType, generateUniqueFilename } from '../../utils/file'\n\ninterface UploadArgs {\n serverURL: string\n apiRoute: string\n file: File\n mimeType: string\n}\n\ninterface UploadResult {\n filename: string\n uploadId?: string\n mimeType: string\n storage: 'mux' | 's3'\n}\n\ninterface MuxCreateUploadResponse {\n url: string\n uploadId: string\n filename: string\n}\n\nconst { logError, throwError } = useErrorHandler()\nconst emitter = useMediaCloudEmitter()\n\nconst MUX_CHUNK_SIZE = 30720\nconst TUS_CHUNK_SIZE = 1024 * 1024\nconst TUS_RETRY_DELAYS = [0, 1000, 2000, 5000]\n\n/**\n * Handles Mux video upload with progress tracking\n * @param args - The upload arguments including file, server URL, and callbacks\n * @returns Promise that resolves to upload result or null if upload fails\n */\nasync function muxUpload(args: UploadArgs): Promise<UploadResult | null> {\n const { file, serverURL, apiRoute, mimeType } = args\n\n const filename = file.name\n try {\n // Request upload URL from Mux\n const response = await fetch(`${serverURL}${apiRoute}/mux/upload`, {\n body: JSON.stringify({ filename, mimeType }),\n credentials: 'include',\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n\n const { url, uploadId } = (await response.json()) as MuxCreateUploadResponse\n\n // Create upchunk uploader\n const uploader = await upchunk.createUpload({\n endpoint: url,\n file,\n chunkSize: MUX_CHUNK_SIZE,\n })\n\n // Add upload to tracker\n emitter.emit('addUpload', {\n filename,\n uploadId,\n polling: false,\n pollingUrl: `${serverURL}${apiRoute}/mux/asset`,\n })\n\n // Set up event handlers\n uploader.on('error', function () {\n logError(MediaCloudErrors.MUX_UPLOAD_ERROR.message)\n toast.error('Video upload failed')\n emitter.emit('removeUpload', { uploadId })\n })\n\n uploader.on('progress', function (progress) {\n emitter.emit('updateUpload', {\n filename,\n progress: progress.detail,\n })\n })\n\n uploader.on('success', function () {\n emitter.emit('uploadComplete', { filename })\n })\n\n // Update collection entry\n // with filename, uploadId, mimeType, and storage\n return {\n filename,\n uploadId,\n mimeType,\n storage: 'mux',\n }\n } catch (_error) {\n logError(MediaCloudErrors.MUX_DIRECT_UPLOAD_ERROR.message)\n toast.error('Video upload failed')\n return null\n }\n}\n\n/**\n * Handles TUS file upload with resumable capabilities\n * @param args - The upload arguments including file, server URL, and callbacks\n * @returns Promise that resolves to upload result or null if upload fails\n */\nasync function tusUpload(args: UploadArgs): Promise<UploadResult | null> {\n const { apiRoute, serverURL, file, mimeType } = args\n\n const filename = file.name\n const filetype = file.type\n const filesize = file.size.toString()\n\n // Clear any stale TUS uploads from localStorage\n Object.keys(localStorage)\n .filter((key) => key.startsWith('tus::'))\n .forEach((key) => localStorage.removeItem(key))\n\n // Flag to prevent multiple onUploadUrlAvailable calls\n let uploadUrlAvailable = false\n let eventListenerAdded = false\n\n function onBeforeUnload(e: BeforeUnloadEvent) {\n window.removeEventListener('beforeunload', onBeforeUnload)\n e.preventDefault()\n }\n\n function onPageUnload() {\n window.removeEventListener('unload', onPageUnload)\n navigator.sendBeacon(\n `${serverURL}${apiRoute}/uploads/cleanup`,\n JSON.stringify({ filename })\n )\n }\n\n return new Promise((resolve) => {\n const upload = new tus.Upload(file, {\n endpoint: `${serverURL}${apiRoute}/uploads`,\n retryDelays: TUS_RETRY_DELAYS,\n chunkSize: TUS_CHUNK_SIZE,\n storeFingerprintForResuming: false,\n metadata: {\n filetype,\n filesize,\n filename,\n contentType: filetype,\n contentLength: filesize,\n contentDisposition: 'inline',\n },\n onError(error) {\n logError(MediaCloudErrors.TUS_UPLOAD_ERROR.message)\n logError(error.message)\n\n // Clean up\n navigator.sendBeacon(\n `${serverURL}${apiRoute}/uploads/cleanup`,\n JSON.stringify({ filename })\n )\n\n // Inform user\n emitter.emit('removeUpload', { filename })\n toast.error('File upload failed')\n resolve(null)\n },\n onBeforeRequest() {\n if (!eventListenerAdded) {\n window.addEventListener('beforeunload', onBeforeUnload)\n window.addEventListener('unload', onPageUnload)\n eventListenerAdded = true\n }\n },\n onProgress: function (bytesUploaded, bytesTotal) {\n const percentage = Math.round((bytesUploaded / bytesTotal) * 100)\n emitter.emit('updateUpload', {\n filename,\n progress: percentage,\n })\n },\n onSuccess() {\n // Clean up beforeunload listener\n window.removeEventListener('beforeunload', onBeforeUnload)\n window.removeEventListener('unload', onPageUnload)\n\n // Mark upload as complete in UI\n emitter.emit('uploadComplete', { filename })\n\n // Trigger post upload processing\n fetch(`${serverURL}${apiRoute}/uploads/${filename}/process`)\n },\n onUploadUrlAvailable: async function () {\n // Prevent multiple callbacks\n if (uploadUrlAvailable) {\n return\n }\n\n // Update flag\n uploadUrlAvailable = true\n\n // Add upload to UI\n emitter.emit('addUpload', { filename })\n\n // Update collection entry\n // with filename, mimeType, and storage\n resolve({\n filename,\n mimeType,\n storage: 's3',\n })\n },\n })\n\n upload.start()\n })\n}\n\nconst { log } = useErrorHandler()\n\nexport const UploadHandler = createClientUploadHandler({\n handler: async function (args) {\n const { serverURL, apiRoute, file, updateFilename } = args\n try {\n const mimeType =\n (await getFileType(file)) || file.type || 'application/octet-stream'\n if (!mimeType) {\n throwError(MediaCloudErrors.FILE_TYPE_UNKNOWN)\n return null\n }\n\n const isVideoFile = await isVideo(file)\n\n // Clone file\n let mappedFile = file\n\n if (!isVideoFile) {\n try {\n // Check if file with same name exists\n const response = await fetch(\n `${serverURL}${apiRoute}/uploads/${file.name}/exists`\n ).catch(() => {})\n\n // If file exists, generate a cloned file with a unique filename\n if (response?.status === 200) {\n log(MediaCloudLogs.S3_STORE_FILE_FOUND)\n\n const newFilename = generateUniqueFilename(file.name)\n mappedFile = new File([file], newFilename, { type: file.type })\n await updateFilename(newFilename)\n }\n } catch (_error) {\n logError(MediaCloudErrors.NAMING_FUNCTION_ERROR.message)\n }\n }\n\n const uploadArgs: UploadArgs = {\n file: mappedFile,\n serverURL,\n apiRoute,\n mimeType,\n }\n\n if (isVideoFile) {\n return await muxUpload(uploadArgs)\n } else {\n return await tusUpload(uploadArgs)\n }\n } catch (error) {\n console.error(\n '[PLUGIN-MEDIA-CLOUD] Upload handler detailed error:',\n error\n )\n logError(MediaCloudErrors.UPLOAD_HANDLER_ERROR.message)\n toast.error(\n `Upload failed: ${error instanceof Error ? error.message : 'Unknown error'}`\n )\n return null\n }\n },\n})\n"],"mappings":";;;;;;;;;;;;AAiCA,MAAM,EAAE,UAAU,eAAe,iBAAiB;AAClD,MAAM,UAAU,sBAAsB;AAEtC,MAAM,iBAAiB;AACvB,MAAM,iBAAiB,OAAO;AAC9B,MAAM,mBAAmB;CAAC;CAAG;CAAM;CAAM;CAAK;;;;;;AAO9C,eAAe,UAAU,MAAgD;CACvE,MAAM,EAAE,MAAM,WAAW,UAAU,aAAa;CAEhD,MAAM,WAAW,KAAK;AACtB,KAAI;EAWF,MAAM,EAAE,KAAK,aAAc,OATV,MAAM,MAAM,GAAG,YAAY,SAAS,cAAc;GACjE,MAAM,KAAK,UAAU;IAAE;IAAU;IAAU,CAAC;GAC5C,aAAa;GACb,QAAQ;GACR,SAAS,EACP,gBAAgB,oBACjB;GACF,CAAC,EAEwC,MAAM;EAGhD,MAAM,WAAW,MAAM,QAAQ,aAAa;GAC1C,UAAU;GACV;GACA,WAAW;GACZ,CAAC;AAGF,UAAQ,KAAK,aAAa;GACxB;GACA;GACA,SAAS;GACT,YAAY,GAAG,YAAY,SAAS;GACrC,CAAC;AAGF,WAAS,GAAG,SAAS,WAAY;AAC/B,YAAS,iBAAiB,iBAAiB,QAAQ;AACnD,SAAM,MAAM,sBAAsB;AAClC,WAAQ,KAAK,gBAAgB,EAAE,UAAU,CAAC;IAC1C;AAEF,WAAS,GAAG,YAAY,SAAU,UAAU;AAC1C,WAAQ,KAAK,gBAAgB;IAC3B;IACA,UAAU,SAAS;IACpB,CAAC;IACF;AAEF,WAAS,GAAG,WAAW,WAAY;AACjC,WAAQ,KAAK,kBAAkB,EAAE,UAAU,CAAC;IAC5C;AAIF,SAAO;GACL;GACA;GACA;GACA,SAAS;GACV;UACM,QAAQ;AACf,WAAS,iBAAiB,wBAAwB,QAAQ;AAC1D,QAAM,MAAM,sBAAsB;AAClC,SAAO;;;;;;;;AASX,eAAe,UAAU,MAAgD;CACvE,MAAM,EAAE,UAAU,WAAW,MAAM,aAAa;CAEhD,MAAM,WAAW,KAAK;CACtB,MAAM,WAAW,KAAK;CACtB,MAAM,WAAW,KAAK,KAAK,UAAU;AAGrC,QAAO,KAAK,aAAa,CACtB,QAAQ,QAAQ,IAAI,WAAW,QAAQ,CAAC,CACxC,SAAS,QAAQ,aAAa,WAAW,IAAI,CAAC;CAGjD,IAAI,qBAAqB;CACzB,IAAI,qBAAqB;CAEzB,SAAS,eAAe,GAAsB;AAC5C,SAAO,oBAAoB,gBAAgB,eAAe;AAC1D,IAAE,gBAAgB;;CAGpB,SAAS,eAAe;AACtB,SAAO,oBAAoB,UAAU,aAAa;AAClD,YAAU,WACR,GAAG,YAAY,SAAS,mBACxB,KAAK,UAAU,EAAE,UAAU,CAAC,CAC7B;;AAGH,QAAO,IAAI,SAAS,YAAY;AA4E9B,EA3Ee,IAAI,IAAI,OAAO,MAAM;GAClC,UAAU,GAAG,YAAY,SAAS;GAClC,aAAa;GACb,WAAW;GACX,6BAA6B;GAC7B,UAAU;IACR;IACA;IACA;IACA,aAAa;IACb,eAAe;IACf,oBAAoB;IACrB;GACD,QAAQ,OAAO;AACb,aAAS,iBAAiB,iBAAiB,QAAQ;AACnD,aAAS,MAAM,QAAQ;AAGvB,cAAU,WACR,GAAG,YAAY,SAAS,mBACxB,KAAK,UAAU,EAAE,UAAU,CAAC,CAC7B;AAGD,YAAQ,KAAK,gBAAgB,EAAE,UAAU,CAAC;AAC1C,UAAM,MAAM,qBAAqB;AACjC,YAAQ,KAAK;;GAEf,kBAAkB;AAChB,QAAI,CAAC,oBAAoB;AACvB,YAAO,iBAAiB,gBAAgB,eAAe;AACvD,YAAO,iBAAiB,UAAU,aAAa;AAC/C,0BAAqB;;;GAGzB,YAAY,SAAU,eAAe,YAAY;IAC/C,MAAM,aAAa,KAAK,MAAO,gBAAgB,aAAc,IAAI;AACjE,YAAQ,KAAK,gBAAgB;KAC3B;KACA,UAAU;KACX,CAAC;;GAEJ,YAAY;AAEV,WAAO,oBAAoB,gBAAgB,eAAe;AAC1D,WAAO,oBAAoB,UAAU,aAAa;AAGlD,YAAQ,KAAK,kBAAkB,EAAE,UAAU,CAAC;AAG5C,UAAM,GAAG,YAAY,SAAS,WAAW,SAAS,UAAU;;GAE9D,sBAAsB,iBAAkB;AAEtC,QAAI,mBACF;AAIF,yBAAqB;AAGrB,YAAQ,KAAK,aAAa,EAAE,UAAU,CAAC;AAIvC,YAAQ;KACN;KACA;KACA,SAAS;KACV,CAAC;;GAEL,CAAC,CAEK,OAAO;GACd;;AAGJ,MAAM,EAAE,QAAQ,iBAAiB;AAEjC,MAAa,gBAAgB,0BAA0B,EACrD,SAAS,eAAgB,MAAM;CAC7B,MAAM,EAAE,WAAW,UAAU,MAAM,mBAAmB;AACtD,KAAI;EACF,MAAM,WACH,MAAM,YAAY,KAAK,IAAK,KAAK,QAAQ;AAC5C,MAAI,CAAC,UAAU;AACb,cAAW,iBAAiB,kBAAkB;AAC9C,UAAO;;EAGT,MAAM,cAAc,MAAM,QAAQ,KAAK;EAGvC,IAAI,aAAa;AAEjB,MAAI,CAAC,YACH,KAAI;AAOF,QALiB,MAAM,MACrB,GAAG,YAAY,SAAS,WAAW,KAAK,KAAK,SAC9C,CAAC,YAAY,GAAG,GAGH,WAAW,KAAK;AAC5B,QAAI,eAAe,oBAAoB;IAEvC,MAAM,cAAc,uBAAuB,KAAK,KAAK;AACrD,iBAAa,IAAI,KAAK,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,KAAK,MAAM,CAAC;AAC/D,UAAM,eAAe,YAAY;;WAE5B,QAAQ;AACf,YAAS,iBAAiB,sBAAsB,QAAQ;;EAI5D,MAAMA,aAAyB;GAC7B,MAAM;GACN;GACA;GACA;GACD;AAED,MAAI,YACF,QAAO,MAAM,UAAU,WAAW;MAElC,QAAO,MAAM,UAAU,WAAW;UAE7B,OAAO;AACd,UAAQ,MACN,uDACA,MACD;AACD,WAAS,iBAAiB,qBAAqB,QAAQ;AACvD,QAAM,MACJ,kBAAkB,iBAAiB,QAAQ,MAAM,UAAU,kBAC5D;AACD,SAAO;;GAGZ,CAAC"}
|