Midday / apps /dashboard /src /utils /upload.ts
Jules
Final deployment with all fixes and verified content
c09f67c
import { stripSpecialCharacters } from "@midday/utils";
import type { SupabaseClient } from "@supabase/supabase-js";
import * as tus from "tus-js-client";
type ResumableUploadParmas = {
file: File;
path: string[];
bucket: string;
onProgress?: (bytesUploaded: number, bytesTotal: number) => void;
};
export async function resumableUpload(
client: SupabaseClient,
{ file, path, bucket, onProgress }: ResumableUploadParmas,
) {
const {
data: { session },
} = await client.auth.getSession();
const filename = stripSpecialCharacters(file.name);
const fullPath = decodeURIComponent([...path, filename].join("/"));
return new Promise((resolve, reject) => {
const upload = new tus.Upload(file, {
endpoint: `https://${process.env.NEXT_PUBLIC_SUPABASE_ID}.supabase.co/storage/v1/upload/resumable`,
retryDelays: [0, 3000, 5000, 10000],
headers: {
authorization: `Bearer ${session?.access_token}`,
// optionally set upsert to true to overwrite existing files
"x-upsert": "true",
},
uploadDataDuringCreation: true,
// Important if you want to allow re-uploading the same file https://github.com/tus/tus-js-client/blob/main/docs/api.md#removefingerprintonsuccess
removeFingerprintOnSuccess: true,
metadata: {
bucketName: bucket,
objectName: fullPath,
contentType: file.type,
cacheControl: "3600",
},
// NOTE: it must be set to 6MB (for now) do not change it
chunkSize: 6 * 1024 * 1024,
onError: (error) => {
reject(error);
},
onProgress,
onSuccess: () => {
resolve({
...upload,
filename,
});
},
});
// Check if there are any previous uploads to continue.
return upload.findPreviousUploads().then((previousUploads) => {
// Found previous uploads so we select the first one.
if (previousUploads.length) {
// @ts-expect-error
upload.resumeFromPreviousUpload(previousUploads[0]);
}
upload.start();
});
});
}