Files
hideyoshi-blog/src/lib/storage/storage.utils.ts
Vitor Hideyoshi 873e372bad
Some checks failed
Build and Test / run-test (20.x) (push) Failing after 1m51s
refactor: update S3StorageAdapter to use publicUrl for object retrieval
2026-04-16 20:21:22 -03:00

58 lines
1.7 KiB
TypeScript

'use client';
import * as storage from '@/lib/storage/storage.external';
import { StorageProvider } from '@/lib/storage/storage.interface';
import { wrap } from '@/utils/types/results';
import { z } from 'zod';
export const FileUploadResp = z.object({
signedUrl: z.string(),
key: z.string(),
});
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 fileKey = await hashFile(file);
const existsResult = await storage.checkExists(fileKey);
if (existsResult) {
const presignedUrl = await storage.getPublicUrl(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');
}
console.log(result.value);
const response = await fetch(result.value, {
method: 'PUT',
headers: { 'Content-Type': file.type },
body: file,
});
if (!response.ok) {
throw new Error('Failed to upload file');
}
const presignedUrl = await storage.getPublicUrl(fileKey);
if (!presignedUrl.ok) {
throw new Error('Failed to retrieve file URL');
}
return { signedUrl: presignedUrl.value, key: fileKey };
});