import { ensureFile } from "$std/fs/ensure_file.ts"; /** * @param src url of file * @param dest destination file. If `useFileName` is true, this should be the destination directory * @param [useFileName] whether to use the inferred file name from `src` */ export async function downloadFile( src: string, dest: string, useFileName?: boolean, ) { if (!(src.startsWith("http://") || src.startsWith("https://"))) { throw new TypeError("URL must start with be http:// or https://"); } const fileName = src.split("/").at(-1); const res = await fetch(src); if (!res.ok) { throw new Deno.errors.BadResource( `Request failed with status ${res.status}`, ); } else if (!res.body) { throw new Deno.errors.UnexpectedEof( `The download url ${src} doesn't contain a file to download`, ); } else if (res.status === 404) { throw new Deno.errors.NotFound( `The requested url "${src}" could not be found`, ); } const blob = await res.blob(); const buffer = await blob.arrayBuffer(); const uint8array = new Uint8Array(buffer); await ensureFile(useFileName ? dest + fileName : dest); await Deno.writeFile(dest, uint8array); }