export interface CdnImportDependencies { adminCheck: () => Promise; fetch: (url: string) => Promise; transaction: ( callback: (transaction: TTransaction) => Promise, ) => Promise; importFile: (file: File, transaction: TTransaction) => Promise; afterImport: () => Promise | void; } function filenameFromDisposition(value: string | null) { return value?.match(/filename="?([^";]+)"?/i)?.[1]; } export async function responseToFile(response: Response) { if (!response.ok) { throw new Error( `File failed to download (${response.status} ${response.statusText})`, ); } const dispositionName = filenameFromDisposition( response.headers.get("Content-Disposition"), ); const pathName = response.url ? decodeURIComponent(new URL(response.url).pathname).match( /\/([^/]+)$/, )?.[1] : undefined; const contentType = response.headers.get("Content-Type")?.split(";")[0]; const extension = contentType?.split("/")[1]; const blob = await response.blob(); return new File( [blob], dispositionName || pathName || `file.${extension || "dat"}`, { type: contentType || blob.type }, ); } export async function fetchToCdnService( urls: string[], dependencies: CdnImportDependencies, ) { if (!(await dependencies.adminCheck())) throw "Unauthorized"; try { return await dependencies.transaction((transaction) => Promise.all( urls.map(async (url) => { const response = await dependencies.fetch(url); return dependencies.importFile( await responseToFile(response), transaction, ); }), ), ); } finally { await dependencies.afterImport(); } }