feat: implement file existence check and improve file upload handling
This commit is contained in:
@@ -11,18 +11,36 @@ export const FileUploadResp = z.object({
|
||||
});
|
||||
export type FileUploadResp = z.infer<StorageProvider>;
|
||||
|
||||
async function hashFile(file: File): Promise<string> {
|
||||
const buffer = await file.arrayBuffer();
|
||||
const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
|
||||
const hex = Array.from(new Uint8Array(hashBuffer))
|
||||
.map((b) => b.toString(16).padStart(2, '0'))
|
||||
.join('');
|
||||
const ext = file.name.split('.').pop();
|
||||
return ext ? `${hex}.${ext}` : hex;
|
||||
}
|
||||
|
||||
export const uploadFile = wrap(async (file: File) => {
|
||||
const uniqueFileKey = crypto.randomUUID();
|
||||
const result = await storage.getPutUrl(uniqueFileKey, file.type);
|
||||
const fileKey = await hashFile(file);
|
||||
|
||||
const existsResult = await storage.checkExists(fileKey);
|
||||
if (existsResult) {
|
||||
const presignedUrl = await storage.getSignedUrl(fileKey);
|
||||
if (!presignedUrl.ok) {
|
||||
throw new Error('Failed to retrieve file URL');
|
||||
}
|
||||
return { signedUrl: presignedUrl.value, key: fileKey };
|
||||
}
|
||||
|
||||
const result = await storage.getPutUrl(fileKey, file.type);
|
||||
if (!result.ok) {
|
||||
throw new Error('File upload failed');
|
||||
}
|
||||
|
||||
const response = await fetch(result.value, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': file.type,
|
||||
},
|
||||
headers: { 'Content-Type': file.type },
|
||||
body: file,
|
||||
});
|
||||
|
||||
@@ -30,12 +48,9 @@ export const uploadFile = wrap(async (file: File) => {
|
||||
throw new Error('Failed to upload file');
|
||||
}
|
||||
|
||||
const presignedUrl = await storage.getSignedUrl(uniqueFileKey);
|
||||
const presignedUrl = await storage.getSignedUrl(fileKey);
|
||||
if (!presignedUrl.ok) {
|
||||
throw new Error('Failed to retrieve file URL');
|
||||
}
|
||||
return {
|
||||
signedUrl: presignedUrl.value,
|
||||
key: uniqueFileKey,
|
||||
};
|
||||
return { signedUrl: presignedUrl.value, key: fileKey };
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user