format import { FlipperServerCommands , FlipperServerEvents } from 'flipper-common' ; import { pathExists } from 'fs-extra' ; import { promises , createWriteStream , ReadStream } from 'fs' ; import axios from 'axios' ; import { v4 as uuid } from 'uuid' ; const { unlink } = promises ; const axiosHttpAdapter = require ( 'axios/lib/adapters/http' ) ; export const commandDownloadFileStartFactory = ( emit ) : FlipperServerCommands [ 'download-file-start' ] => async ( url , dest , { method = 'GET' , timeout , maxRedirects , headers , overwrite } = { } ) => { const destExists = await pathExists ( dest ) ; if ( destExists ) { if ( ! overwrite ) { throw new Error ( 'FlipperServerImpl -> executing "download-file" -> path already exists and overwrite set to false' ) ; } await unlink ( dest ) ; } const downloadId = uuid ( ) ; const response = await axios . request < ReadStream > ( { method , url , responseType : 'stream' , adapter : axiosHttpAdapter , timeout , maxRedirects , headers , } ) ; let totalSize = parseInt ( response . headers [ 'content-length' ] , 10 ) ; if ( Number . isNaN ( totalSize ) ) { totalSize = 0 ; } const writeStream = response . data . pipe ( createWriteStream ( dest , { autoClose : true } ) ) ; let downloaded = 0 ; response . data . on ( 'data' , ( data ) => { downloaded += Buffer . byteLength ( data ) ; emit ( 'download-file-update' , { id : downloadId , downloaded , totalSize , status : 'downloading' , } ) ; } ) ; response . data . on ( 'error' , ( e ) => { writeStream . destroy ( e ) ; } ) ; writeStream . on ( 'finish' , ( ) => { emit ( 'download-file-update' , { id : downloadId , downloaded , totalSize , status : 'success' , } ) ; } ) ; writeStream . on ( 'error' , ( e ) => { response . data . destroy ( ) ; emit ( 'download-file-update' , { id : downloadId , downloaded , totalSize , status : 'error' , message : e . message , stack : e . stack , } ) ; } ) ; return { id : downloadId , headers : response . headers , status : response . status , statusText : response . statusText , totalSize , } ; } ;