'use strict'; var _templateObject = _taggedTemplateLiteral(['\n URL: ', '\n ', '\n '], ['\n URL: ', '\n ', '\n ']), _templateObject2 = _taggedTemplateLiteral(['\n Failed downloading the Cypress binary.\n Response code: ', '\n Response message: ', '\n '], ['\n Failed downloading the Cypress binary.\n Response code: ', '\n Response message: ', '\n ']); function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } var _ = require('lodash'); var os = require('os'); var path = require('path'); var progress = require('request-progress'); var Promise = require('bluebird'); var request = require('request'); var url = require('url'); var debug = require('debug')('cypress:cli'); var _require = require('common-tags'), stripIndent = _require.stripIndent; var is = require('check-more-types'); var _require2 = require('../errors'), throwFormErrorText = _require2.throwFormErrorText, errors = _require2.errors; var fs = require('../fs'); var util = require('../util'); var info = require('./info'); var baseUrl = 'https://download.cypress.io/'; var prepend = function prepend(urlPath) { var endpoint = url.resolve(baseUrl, urlPath); var platform = os.platform(); var arch = os.arch(); return endpoint + '?platform=' + platform + '&arch=' + arch; }; var getUrl = function getUrl(version) { if (is.url(version)) { debug('version is already an url', version); return version; } return version ? prepend('desktop/' + version) : prepend('desktop'); }; var statusMessage = function statusMessage(err) { return err.statusCode ? [err.statusCode, err.statusMessage].join(' - ') : err.toString(); }; var prettyDownloadErr = function prettyDownloadErr(err, version) { var msg = stripIndent(_templateObject, getUrl(version), statusMessage(err)); debug(msg); return throwFormErrorText(errors.failedDownload)(msg); }; // attention: // when passing relative path to NPM post install hook, the current working // directory is set to the `node_modules/cypress` folder // the user is probably passing relative path with respect to root package folder function formAbsolutePath(filename) { if (path.isAbsolute(filename)) { return filename; } return path.join(process.cwd(), '..', '..', filename); } // downloads from given url // return an object with // {filename: ..., downloaded: true} var downloadFromUrl = function downloadFromUrl(options) { return new Promise(function (resolve, reject) { var url = getUrl(options.version); debug('Downloading from', url); debug('Saving file to', options.downloadDestination); var req = request({ url: url, followRedirect: function followRedirect(response) { var version = response.headers['x-version']; if (version) { // set the version in options if we have one. // this insulates us from potential redirect // problems where version would be set to undefined. options.version = version; } // yes redirect return true; } }); // closure var started = null; progress(req, { throttle: options.throttle }).on('response', function (response) { // start counting now once we've gotten // response headers started = new Date(); // if our status code does not start with 200 if (!/^2/.test(response.statusCode)) { debug('response code %d', response.statusCode); var err = new Error(stripIndent(_templateObject2, response.statusCode, response.statusMessage)); reject(err); } }).on('error', reject).on('progress', function (state) { // total time we've elapsed // starting on our first progress notification var elapsed = new Date() - started; var eta = util.calculateEta(state.percent, elapsed); // send up our percent and seconds remaining options.onProgress(state.percent, util.secsRemaining(eta)); }) // save this download here .pipe(fs.createWriteStream(options.downloadDestination)).on('finish', function () { debug('downloading finished'); resolve({ filename: options.downloadDestination, downloaded: true }); }); }); }; // returns an object with zip filename // and a flag if the file was really downloaded // or not. Maybe it was already there! // {filename: ..., downloaded: true|false} var download = function download() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; if (!options.version) { debug('empty Cypress version to download, will try latest'); return downloadFromUrl(options); } debug('need to download Cypress version %s', options.version); // first check the original filename return fs.pathExists(options.version).then(function (exists) { if (exists) { debug('found file right away', options.version); return { filename: options.version, downloaded: false }; } var possibleFile = formAbsolutePath(options.version); debug('checking local file', possibleFile, 'cwd', process.cwd()); return fs.pathExists(possibleFile).then(function (exists) { if (exists) { debug('found local file', possibleFile); debug('skipping download'); return { filename: possibleFile, downloaded: false }; } else { return downloadFromUrl(options); } }); }); }; var start = function start(options) { _.defaults(options, { version: null, throttle: 100, onProgress: function onProgress() {}, downloadDestination: path.join(info.getInstallationDir(), 'cypress.zip') }); // make sure our 'dist' installation dir exists return info.ensureInstallationDir().then(function () { return download(options); }).catch(function (err) { return prettyDownloadErr(err, options.version); }); }; module.exports = { start: start, getUrl: getUrl };