dstpabuaran.com/resources/js/lib/upload.ts
Yoga Pangestu 23cc327190 Refactor code for improved readability and consistency across multiple files
- Adjusted indentation and formatting in login, permissions, profile, and security pages for better readability.
- Enhanced the clarity of conditional statements and function calls in permissions and profile components.
- Updated type definitions in vite-env.d.ts for better code structure.
- Cleaned up array mapping syntax in ProductTest.php for consistency.
2026-08-01 10:14:47 +07:00

93 lines
2.4 KiB
TypeScript

const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
const ALLOWED_TYPES = ['image/jpeg', 'image/png', 'image/webp', 'image/gif'];
export type PresignedUrlResponse = {
upload_url: string;
key: string;
uuid: string;
};
export class UploadError extends Error {
constructor(message: string) {
super(message);
this.name = 'UploadError';
}
}
function getSessionCookie(): string {
return (
document.cookie
.split('; ')
.find((c) => c.startsWith('XSRF-TOKEN='))
?.split('=')[1] ?? ''
);
}
export async function requestPresignedUrl(
fileName: string,
mimeType: string,
folder?: string,
): Promise<PresignedUrlResponse> {
const response = await fetch('/api/presigned-url', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
'X-XSRF-TOKEN': decodeURIComponent(getSessionCookie()),
},
body: JSON.stringify({
file_name: fileName,
mime_type: mimeType,
folder,
}),
});
if (!response.ok) {
const data = await response.json().catch(() => null);
throw new UploadError(data?.message ?? 'Gagal membuat URL upload.');
}
return response.json();
}
export async function uploadToS3(uploadUrl: string, file: File): Promise<void> {
const response = await fetch(uploadUrl, {
method: 'PUT',
body: file,
headers: {
'Content-Type': file.type,
},
});
if (!response.ok) {
throw new UploadError('Gagal mengunggah file ke storage.');
}
}
export async function uploadFile(file: File, folder?: string): Promise<string> {
if (!ALLOWED_TYPES.includes(file.type)) {
throw new UploadError(
'Tipe file tidak didukung. Hanya JPG, PNG, WebP, dan GIF yang diizinkan.',
);
}
if (file.size > MAX_FILE_SIZE) {
throw new UploadError('Ukuran file melebihi batas 10MB.');
}
const { upload_url, key } = await requestPresignedUrl(
file.name,
file.type,
folder,
);
await uploadToS3(upload_url, file);
return key;
}
export function getTemporaryUrl(key: string, minutes = 60): string {
return `/api/presigned-url/${encodeURIComponent(key)}?minutes=${minutes}`;
}