File/downloadFile.js

import hasWebAccess from './hasWebAccess'
/**
 * An async function which downloads a file via node's http or https.
 *
 * @function downloadFile
 * @async
 * @since 1.0.0
 * @memberof module:File
 * @see {@link module:File.hasWebAccess|hasWebAccess}
 *
 * @param {object} config - A configuration object.
 * @param {string}  config.url - The url to the file you want to download
 * @param {number}  [config.port=443] - The port number to use
 * @param {object}  [config.agent=http.globalAgent] - How much gold the party starts with.
 *
 * @returns {Promise} - Returns a promise that resolves the file's data
 * from the url
 * @example
 * import {downloadFile, tryWriteFile} from 'fenix-tools'
 *
 * downloadFile({
 *  url: 'http://fenixenginemv.gitlab.io/img/fenix-logo-signature.png'
 * port: 80,
 * })
 * .then(data => {
 *   console.log(data) // => The downloaded file's data
 *   tryWriteFile('/', data) // => writes file to machine
 * })
 *
 */
export default async function downloadFile (config = {}) {
  if (!config.url) {
    return new Error('A url is required to download a file')
  }
  await hasWebAccess()
  const url = require('url')
  const downloadUrl = url.parse(config.url)
  const https = downloadUrl.protocol === 'https:' ? require('https') : require('http')
  const httpsConfig = {
    hostname: downloadUrl.hostname,
    port: config.port || 443,
    path: downloadUrl.href,
    protocol: downloadUrl.protocol,
    agent: config.agent || https.globalAgent
  }
  await new Promise((resolve, reject) => {
    https.get(httpsConfig,
      (response) => {
        const chunks = []
        const status = response.statusCode
        if (status !== 200) {
          throw new Error(`Failed to load, reasponse status code is ${status}`)
        }
        response.on('data', (chunk) => chunks.push(chunk))
        response.on('end', () => resolve(chunks.join('')))
        response.on('error', (err) => reject(err))
      })
  })
}