export class FileDownloader { static async download(url, filename) { const downloadUrl = this.originalDownloadUrl(url); try { const response = await fetch(downloadUrl); if (!response.ok) throw new Error('Gagal mengunduh berkas.'); const blob = await response.blob(); const blobUrl = URL.createObjectURL(blob); this._click(blobUrl, filename); URL.revokeObjectURL(blobUrl); } catch (err) { console.warn('Unduh via Blob gagal, beralih ke parameter Directus:', err); this._click(downloadUrl, filename); } } static originalDownloadUrl(url) { if (!url) return ''; const hashIndex = url.indexOf('#'); const hash = hashIndex >= 0 ? url.slice(hashIndex) : ''; const base = hashIndex >= 0 ? url.slice(0, hashIndex) : url; if (/(^|[?&])download(?:[=&]|$)/.test(base)) return url; return `${base}${base.includes('?') ? '&' : '?'}download${hash}`; } static _click(href, filename) { const a = document.createElement('a'); a.style.display = 'none'; a.href = href; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); } }