40 lines
1.3 KiB
TypeScript
40 lines
1.3 KiB
TypeScript
|
import { FileDownloadLocation, FileDownloadParameters, FileLocation, ITelegramClient } from '@mtcute/core'
|
||
|
import { downloadAsIterable } from '@mtcute/core/methods.js'
|
||
|
|
||
|
import { writeAll } from '@std/io/write-all'
|
||
|
|
||
|
/**
|
||
|
* Download a remote file to a local file (only for NodeJS).
|
||
|
* Promise will resolve once the download is complete.
|
||
|
*
|
||
|
* @param filename Local file name to which the remote file will be downloaded
|
||
|
* @param params File download parameters
|
||
|
*/
|
||
|
export async function downloadToFile(
|
||
|
client: ITelegramClient,
|
||
|
filename: string,
|
||
|
location: FileDownloadLocation,
|
||
|
params?: FileDownloadParameters,
|
||
|
): Promise<void> {
|
||
|
if (location instanceof FileLocation && ArrayBuffer.isView(location.location)) {
|
||
|
// early return for inline files
|
||
|
await Deno.writeFile(filename, location.location)
|
||
|
}
|
||
|
|
||
|
const fd = await Deno.open(filename, { write: true, create: true, truncate: true })
|
||
|
|
||
|
if (params?.abortSignal) {
|
||
|
params.abortSignal.addEventListener('abort', () => {
|
||
|
client.log.debug('aborting file download %s - cleaning up', filename)
|
||
|
fd.close()
|
||
|
Deno.removeSync(filename)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
for await (const chunk of downloadAsIterable(client, location, params)) {
|
||
|
await writeAll(fd, chunk)
|
||
|
}
|
||
|
|
||
|
fd.close()
|
||
|
}
|