<commit_before>var fs   = require('fs');
var path = require('path');

// Constant for showing surrounding context, can be set with env variable
var context = parseInt(process.env['COFFEE_BACKTRACE_CONTEXT']);
// We have to allow "0" as a valid context, so we can't just || this part.
if (isNaN(context)) context = 3;
// The time when this script was run, which we can use to test if the source was
// modified or not since being compiled.
var safeTime = new Date();
// Our coffee package
var coffee;

function logErr(msg) {
  process.stderr.write(msg.toString() + '\n');
}

// Color the lines red and highlight one of them. Add > and >> respectively so
// that it is still readable in non-color environments.
function color(lines, highlight) {
  return lines.map(function(line, num){
    // At the end/beginning of file, it could be undefined
    if (typeof line === 'string') {
      if (num === highlight)
        return '\x1b[1;31m>>' + line + '\x1b[0m';
      else
        return '\x1b[31m> ' + line + '\x1b[0m';
    }
  });
}

// Takes a stack and maps each line to a possible CoffeeScript compiled printout
function expandStack(stack) {
  var sources = {};
  return stack.split('\n').slice(1).map(function(loc) {
    // We can't evaluate it if it isn't CoffeeScript
    if (!/\.coffee:\d/.test(loc))
      return null;

    // For the rest, get the file. `match` is formatted as:
    // [match, path, line, col]
    var match = loc.match(/\((.+\.coffee):(\d+):(\d+)/);
    var path = match[1];
    var line = match[2];

    // If we cannot read this off the filesystem for whatever reason, just skip it
    try {
      // Make sure the source was not changed since we started
      if (fs.statSync(path).mtime > safeTime)
        return color(["Source of " + path.basename(path) + " updated; cannot find line"]);
    } catch (err) { return null; }

    // So now we have a reliable source file. Get it and find the line. Again,
    // being (unnecessarily?) careful with the filesystem access functions.
    try {
      line = parseInt(line) - 1;
      if (sources[path] === undefined)
        sources[path] = coffee.compile(fs.readFileSync(path, 'utf8'));

      // Grab the context lines and color them
      var contents = sources[path].split('\n').slice(line - context, line + context + 1);
      return color(contents, context).join('\n');
    } catch (err) { return null; }
  });
}

// Handles a thrown exception by printing a reasonable stack trace
function errorHandler(error) {
  // If we can't get information about the stack (e.g., if you threw something
  // that was not an Error), we can't do anything here.
  if (!error || typeof error.stack !== 'string') {
    throw error;
  }

  // We absolutely do not want this to error
  var expanded = [];
  try {
    expanded = expandStack(error.stack);
  } catch (err) {
    require('util').debug(err);
  };

  var trace = error.stack.split('\n');
  // Print first line normally
  logErr(trace[0]);
  // For each other line, print with expanded if necessary
  trace.slice(1).forEach(function(stack, i) {
    logErr(stack);
    if (expanded[i])
      logErr(expanded[i]);
  });
  process.exit(1);
}

// This is the tricky part. There are two cases that we must handle. Firstly, if
// you run `coffee <file>` and it throws an uncaught exception, it will bubble
// up to coffee's try-catch block and be printed to the screen. It does trigger
// an event though, but there's a catch: when you run `coffee` it is using
// whichever one it finds on the path, which means that the correct one is not
// necessarily node_modules/coffee-script. So we find the executable and then
// require the corresponding object so we can bind an event to it.
// Note that this should still work fine if it was symlinked.
if (path.basename(process.execPath) == 'coffee') {
  var coffeePath = path.join(process.execPath, '../../lib/coffee-script/coffee-script.js')
  // We don't want to interrupt the start-up process, so let's be kind here.
  try {
    // Get the reference to the correct CoffeeScript object (the one with the
    // EventEmitter attached to it) and bind to failure
    coffee = require(coffeePath);
    coffee.on('failure', errorHandler);
  } catch (err) {
    logErr('coffee-backtrace could not attach listener: ' + err.toString() + '\n');
  }
}

// We also need to listen to node's error handler, as coffee does not catch
// everything. Things that are done, say, in a setTimeout will bubble up to
// node.
process.on('uncaughtException', errorHandler)

// Export settings
module.exports = {
  setContext: function(num) {
    context = num;
    return this;
  }
};
<commit_msg>Fixed a bug with local path variable<commit_after>var fs   = require('fs');
var path = require('path');

// Constant for showing surrounding context, can be set with env variable
var context = parseInt(process.env['COFFEE_BACKTRACE_CONTEXT']);
// We have to allow "0" as a valid context, so we can't just || this part.
if (isNaN(context)) context = 3;
// The time when this script was run, which we can use to test if the source was
// modified or not since being compiled.
var safeTime = new Date();
// Our coffee package
var coffee;

function logErr(msg) {
  process.stderr.write(msg.toString() + '\n');
}

// Color the lines red and highlight one of them. Add > and >> respectively so
// that it is still readable in non-color environments.
function color(lines, highlight) {
  return lines.map(function(line, num){
    // At the end/beginning of file, it could be undefined
    if (typeof line === 'string') {
      if (num === highlight)
        return '\x1b[1;31m>>' + line + '\x1b[0m';
      else
        return '\x1b[31m> ' + line + '\x1b[0m';
    }
  });
}

// Takes a stack and maps each line to a possible CoffeeScript compiled printout
function expandStack(stack) {
  var sources = {};
  return stack.split('\n').slice(1).map(function(loc) {
    // We can't evaluate it if it isn't CoffeeScript
    if (!/\.coffee:\d/.test(loc))
      return null;

    // For the rest, get the file. `match` is formatted as:
    // [match, path, line, col]
    var match = loc.match(/\((.+\.coffee):(\d+):(\d+)/);
    var file = match[1];
    var line = match[2];

    // If we cannot read this off the filesystem for whatever reason, just skip it
    try {
      // Make sure the source was not changed since we started
      if (fs.statSync(file).mtime > safeTime)
        return color(["Source of " + path.basename(file) + " updated; cannot find line"]);
    } catch (err) { return null; }

    // So now we have a reliable source file. Get it and find the line. Again,
    // being (unnecessarily?) careful with the filesystem access functions.
    try {
      line = parseInt(line) - 1;
      if (sources[file] === undefined)
        sources[file] = coffee.compile(fs.readFileSync(file, 'utf8'));

      // Grab the context lines and color them
      var contents = sources[file].split('\n').slice(line - context, line + context + 1);
      return color(contents, context).join('\n');
    } catch (err) { return null; }
  });
}

// Handles a thrown exception by printing a reasonable stack trace
function errorHandler(error) {
  // If we can't get information about the stack (e.g., if you threw something
  // that was not an Error), we can't do anything here.
  if (!error || typeof error.stack !== 'string') {
    throw error;
  }

  // We absolutely do not want this to error
  var expanded = [];
  try {
    expanded = expandStack(error.stack);
  } catch (err) {
    require('util').debug(err);
  };

  var trace = error.stack.split('\n');
  // Print first line normally
  logErr(trace[0]);
  // For each other line, print with expanded if necessary
  trace.slice(1).forEach(function(stack, i) {
    logErr(stack);
    if (expanded[i])
      logErr(expanded[i]);
  });
  process.exit(1);
}

// This is the tricky part. There are two cases that we must handle. Firstly, if
// you run `coffee <file>` and it throws an uncaught exception, it will bubble
// up to coffee's try-catch block and be printed to the screen. It does trigger
// an event though, but there's a catch: when you run `coffee` it is using
// whichever one it finds on the path, which means that the correct one is not
// necessarily node_modules/coffee-script. So we find the executable and then
// require the corresponding object so we can bind an event to it.
// Note that this should still work fine if it was symlinked.
if (path.basename(process.execPath) == 'coffee') {
  var coffeePath = path.join(process.execPath, '../../lib/coffee-script/coffee-script.js')
  // We don't want to interrupt the start-up process, so let's be kind here.
  try {
    // Get the reference to the correct CoffeeScript object (the one with the
    // EventEmitter attached to it) and bind to failure
    coffee = require(coffeePath);
    coffee.on('failure', errorHandler);
  } catch (err) {
    logErr('coffee-backtrace could not attach listener: ' + err.toString() + '\n');
  }
}

// We also need to listen to node's error handler, as coffee does not catch
// everything. Things that are done, say, in a setTimeout will bubble up to
// node.
process.on('uncaughtException', errorHandler)

// Export settings
module.exports = {
  setContext: function(num) {
    context = num;
    return this;
  }
};
<|endoftext|>


<commit_before>var util = require('util');

var Command = require('./command.js');
var Query = require('./query.js');
var Packets = require('../packets/index.js');

var objectAssign = require('object-assign');

var compileParser = require('../compile_binary_parser.js');

function Execute (options, callback)
{
  Command.call(this);
  this.statement = options.statement;
  this.sql = options.sql;
  this.values = options.values;
  this.onResult = callback;
  this.parameters = options.values;

  this.insertId = 0;

  this._rows = [];
  this._fields = [];
  this._result = [];
  this._fieldCount = 0;
  this._rowParser = null;
  this._executeOptions = options;
  this._resultIndex = 0;
  this._localStream = null;
  this._unpipeStream = function () {};
  this._streamFactory = options.infileStreamFactory;
}
util.inherits(Execute, Command);

Execute.prototype.buildParserFromFields = function (fields, connection) {
  var parserKey = connection.keyFromFields(fields, this.options);
  var parser = connection.binaryProtocolParsers[parserKey];
  if (!parser) {
    parser = compileParser(fields, this.options, connection.config);
    connection.binaryProtocolParsers[parserKey] = parser;
  }
  return parser;
};

Execute.prototype.start = function (packet, connection) {
  this.options = objectAssign({}, connection.config, this._executeOptions);
  var executePacket = new Packets.Execute(this.statement.id, this.parameters, connection.config.charsetNumber);
  connection.writePacket(executePacket.toPacket(1));
  return Execute.prototype.resultsetHeader;
};

Execute.prototype.done = Query.prototype.done;
Execute.prototype.doneInsert = Query.prototype.doneInsert;
Execute.prototype.resultsetHeader = Query.prototype.resultsetHeader;
Execute.prototype._findOrCreateReadStream = Query.prototype._findOrCreateReadStream;
Execute.prototype._streamLocalInfile = Query.prototype._streamLocalInfile;
Execute.prototype.row = Query.prototype.row;
Execute.prototype.stream = Query.prototype.stream;

Execute.prototype.readField = function (packet, connection) {
  var def, fields;

  // disabling for now, but would be great to find reliable way to parse fields only once
  // fields reported by prepare can be empty at all or just incorrect - see #169
  //
  // perfomance optimisation: if we already have this field parsed in statement header, use one from header
  // var field = this.statement.columns.length == this._fieldCount ?
  //  this.statement.columns[this._receivedFieldsCount] : new Packets.ColumnDefinition(packet);

  var field = new Packets.ColumnDefinition(packet);

  this._receivedFieldsCount++;
  this._fields[this._resultIndex].push(field);
  if (this._receivedFieldsCount == this._fieldCount) {
    fields = this._fields[this._resultIndex];
    this.emit('fields', fields, this._resultIndex);
    return Execute.prototype.fieldsEOF;
  }
  return Execute.prototype.readField;
};

Execute.prototype.fieldsEOF = function (packet, connection) {
  // check EOF
  if (!packet.isEOF()) {
    return connection.protocolError('Expected EOF packet');
  }
  this._rowParser = this.buildParserFromFields(this._fields[this._resultIndex], connection);
  return Execute.prototype.row;
};

module.exports = Execute;
<commit_msg>fix Query.stream exception on prepared statements<commit_after>var util = require('util');

var Command = require('./command.js');
var Query = require('./query.js');
var Packets = require('../packets/index.js');

var objectAssign = require('object-assign');

var compileParser = require('../compile_binary_parser.js');

function Execute (options, callback)
{
  Command.call(this);
  this.statement = options.statement;
  this.sql = options.sql;
  this.values = options.values;
  this.onResult = callback;
  this.parameters = options.values;

  this.insertId = 0;

  this._rows = [];
  this._fields = [];
  this._result = [];
  this._fieldCount = 0;
  this._rowParser = null;
  this._executeOptions = options;
  this._resultIndex = 0;
  this._localStream = null;
  this._unpipeStream = function () {};
  this._streamFactory = options.infileStreamFactory;
  this._connection = null;
}
util.inherits(Execute, Command);

Execute.prototype.buildParserFromFields = function (fields, connection) {
  var parserKey = connection.keyFromFields(fields, this.options);
  var parser = connection.binaryProtocolParsers[parserKey];
  if (!parser) {
    parser = compileParser(fields, this.options, connection.config);
    connection.binaryProtocolParsers[parserKey] = parser;
  }
  return parser;
};

Execute.prototype.start = function (packet, connection) {
  this._connection = connection;
  this.options = objectAssign({}, connection.config, this._executeOptions);
  var executePacket = new Packets.Execute(this.statement.id, this.parameters, connection.config.charsetNumber);
  connection.writePacket(executePacket.toPacket(1));
  return Execute.prototype.resultsetHeader;
};

Execute.prototype.done = Query.prototype.done;
Execute.prototype.doneInsert = Query.prototype.doneInsert;
Execute.prototype.resultsetHeader = Query.prototype.resultsetHeader;
Execute.prototype._findOrCreateReadStream = Query.prototype._findOrCreateReadStream;
Execute.prototype._streamLocalInfile = Query.prototype._streamLocalInfile;
Execute.prototype.row = Query.prototype.row;
Execute.prototype.stream = Query.prototype.stream;

Execute.prototype.readField = function (packet, connection) {
  var def, fields;

  // disabling for now, but would be great to find reliable way to parse fields only once
  // fields reported by prepare can be empty at all or just incorrect - see #169
  //
  // perfomance optimisation: if we already have this field parsed in statement header, use one from header
  // var field = this.statement.columns.length == this._fieldCount ?
  //  this.statement.columns[this._receivedFieldsCount] : new Packets.ColumnDefinition(packet);

  var field = new Packets.ColumnDefinition(packet);

  this._receivedFieldsCount++;
  this._fields[this._resultIndex].push(field);
  if (this._receivedFieldsCount == this._fieldCount) {
    fields = this._fields[this._resultIndex];
    this.emit('fields', fields, this._resultIndex);
    return Execute.prototype.fieldsEOF;
  }
  return Execute.prototype.readField;
};

Execute.prototype.fieldsEOF = function (packet, connection) {
  // check EOF
  if (!packet.isEOF()) {
    return connection.protocolError('Expected EOF packet');
  }
  this._rowParser = this.buildParserFromFields(this._fields[this._resultIndex], connection);
  return Execute.prototype.row;
};

module.exports = Execute;
<|endoftext|>


<commit_before>// Copyright & License details are available under JXCORE_LICENSE file

var fs = require('fs');
var path = require('path');
var jxtools = require('jxtools');
var fname = 'io.jxcore.node.jx';
var dname = 'io.jxcore.node';
var common = require('../common.js');
var config = require('./config.js');

var localFile = path.join(process.cwd(), fname);
var folder = path.join(process.cwd(), dname);

var unpack = function (cb) {

  var commands = [];

  if (fs.existsSync(folder)) {
    commands.push({
      name: 'remove_plugin',
      command: 'cordova plugins remove ' + dname,
      caption: 'Removing plugin from project...',
      skip_error: true
    });
    commands.push({
      name: 'remove_dir',
      command: jxtools.fs.getRmdirCommand(folder),
      caption: 'Removing previous plugin\'s folder...'
    });
  }

  // extract package
  commands.push({
    name: 'extract',
    command: '"' + process.execPath + '" ' + fname,
    caption: 'Extracting plugin package...'
  });

  // add plugin
  commands.push({
    name: 'add_plugin',
    command: 'cordova plugins add ' + dname,
    caption: 'Adding plugin to project...'
  });

  commands.push({
    name: 'remove_dir_after',
    command: jxtools.fs.getRmdirCommand(folder),
    caption: 'Cleaning up...'
  });

  jxtools.fs.execMultiple(commands, function (ret) {
    if (ret.errors)
      return cb(ret.errors);
    else {
      var sampleName = jxcore.utils.argv.getValue('sample');
      if (sampleName) {
        var sample = require('./sample.js');
        sample.useSample(sampleName, function (err) {
          if (!err)
            jxcore.utils.console.info("Done.");

          cb(err);
        });
      }
    }
  });
};

var download = function (version, cb) {

  //var url = 'https://raw.githubusercontent.com/jxcore/jxcore-cordova-release/master/' + version + '/' + fname;
  var url = 'http://jxcordova.cloudapp.net/' + version + '/' + fname;
  var download = jxtools.http.download(url, fname, {attempts: 3, timeout: 10000});
  download.on('end', function (err) {
    if (!err)
      unpack(cb);
  });
};

var install = function(version, cb) {

  var offFile = checkOfflinePackage(version);
  var copied = false;
  if (offFile) {
    try {
      fs.writeFileSync(localFile, fs.readFileSync(offFile));
      copied = true;
    } catch (ex) {
      jxcore.utils.console.warn('Cannot use offline file: ' + ex);
    }

    if (copied) {
      jxtools.console.logPair('Using offline file:', offFile);
      return unpack(cb);
    }
  }

  // downloading if offline file is not used
  download(version, cb);
};

var checkOfflinePackage = function(version) {
  var cfg = config.read();
  if (cfg.err)
    return false;

  var offDir = cfg['offline-dir'] || process.cwd();
  var offFile = path.join(offDir, version, fname);
  return fs.existsSync(offFile) ? offFile : false;
};

var getLatestCordovaVersion = function (cb) {

  var _url = 'https://raw.githubusercontent.com/jxcore/jxcore-cordova/master/package.json';
  jxtools.http.downloadString(_url, {silent: true}, function (err, json_str) {
    if (!err) {
      var version = 'unknown';
      try {
        var json = JSON.parse(json_str);
        version = json.version;
      } catch (ex) {
        return cb("Cannot parse package.json: " + ex);
      }

      cb(false, version);
    } else {
      cb(err);
    }
  });
};

exports.run = function (cb) {

  var parsedArgv = jxcore.utils.argv.parse();

  if (fs.existsSync(localFile)) {
    var stat = fs.statSync(localFile);
    if (stat.size < 1024 * 1024)
      fs.unlinkSync(localFile);
  }

  if (fs.existsSync(localFile) && !parsedArgv.force) {
    jxcore.utils.console.warn('Skipping the download, since file', fname, 'already exists.');
    jxcore.utils.console.log('If you want to force downloading, use --force option.');
    unpack(cb);
    return;
  }

  if (fs.existsSync(folder) && !parsedArgv.force) {
    jxcore.utils.console.warn('Skipping the installation, since folder', dname, 'already exists.');
    jxcore.utils.console.log('If you want to force installing, use --force option.');
    return;
  }

  var plugin_installed_folder = path.join(process.cwd(), 'plugins', dname);
  if (fs.existsSync(plugin_installed_folder) && !parsedArgv.force) {
    jxcore.utils.console.warn('Skipping the installation, since plugin is already added.');
    jxcore.utils.console.log('If you want to force installing, use --force option or remove the plugin:');
    jxcore.utils.console.log('    > cordova plugins remove ' + dname);
    return;
  }

  var argv3 = process.argv[3];
  if (argv3 && argv3.slice(0, 1) === '-')
    argv3 = null;

  if (argv3) {
    install(argv3, cb);
  } else {
    getLatestCordovaVersion(function(err, version) {
      if (err)
        jxcore.utils.console.error(err);
      else {
        jxtools.console.logPair('Latest jxcore-cordova version:', version);
        install(version, cb);
      }
    });
  }

};

<commit_msg>use cached files<commit_after>// Copyright & License details are available under JXCORE_LICENSE file

var fs = require('fs');
var path = require('path');
var jxtools = require('jxtools');
var fname = 'io.jxcore.node.jx';
var dname = 'io.jxcore.node';
var common = require('../common.js');
var config = require('./config.js');

var localFile = path.join(process.cwd(), fname);
var folder = path.join(process.cwd(), dname);

var writeToCache = function(version) {
  // for now supports only default path commmon.cacheDir

  var dir = path.join(common.cacheDir, version);
  var file = path.join(dir, fname);

  if (!fs.existsSync(common.cacheDir))
      fs.mkdirSync(common.cacheDir);

  if (!fs.existsSync(dir))
    fs.mkdirSync(dir);

  fs.writeFileSync(file, fs.readFileSync(localFile));
};

var unpack = function (version, cb) {

  var commands = [];

  var cfg = config.read();
  var _writeToCache = !cfg.err && cfg.cache === true;

  if (_writeToCache && version) {
    commands.push({
      name: 'write_to_cache',
      command: function() {
        writeToCache(version);
      },
      caption: 'Saving file to cache...',
      skip_error: true
    });
  }

  if (fs.existsSync(folder)) {
    commands.push({
      name: 'remove_plugin',
      command: 'cordova plugins remove ' + dname,
      caption: 'Removing plugin from project...',
      skip_error: true
    });
    commands.push({
      name: 'remove_dir',
      command: jxtools.fs.getRmdirCommand(folder),
      caption: 'Removing previous plugin\'s folder...'
    });
  }

  var extract = {
    name: 'extract',
    command: '"' + process.execPath + '" ' + fname,
    caption: 'Extracting plugin package...'
  };

  if (cfg.cache)
    extract.postErrorMessage = 'If you see this error too often, you may try to add --force-download option.';

  // extract package
  commands.push(extract);

  // add plugin
  commands.push({
    name: 'add_plugin',
    command: 'cordova plugins add ' + dname,
    caption: 'Adding plugin to project...'
  });

  commands.push({
    name: 'remove_dir_after',
    command: jxtools.fs.getRmdirCommand(folder),
    caption: 'Cleaning up...'
  });

  jxtools.fs.execMultiple(commands, function (ret) {
    if (ret.errors)
      return cb(ret.errors);
    else {
      var sampleName = jxcore.utils.argv.getValue('sample');
      if (sampleName) {
        var sample = require('./sample.js');
        sample.useSample(sampleName, function (err) {
          if (!err)
            jxcore.utils.console.info("Done.");

          cb(err);
        });
      }
    }
  });
};

var download = function (version, cb) {

  //var url = 'https://raw.githubusercontent.com/jxcore/jxcore-cordova-release/master/' + version + '/' + fname;
  var url = 'http://jxcordova.cloudapp.net/' + version + '/' + fname;
  var download = jxtools.http.download(url, fname, {attempts: 3, timeout: 10000});
  download.on('end', function (err) {
    if (!err)
      unpack(version, cb);
  });
};

var install = function(version, cb) {

  var parsedArgv = jxcore.utils.argv.parse();

  var offFile = checkCachedPackage(version);
  var copied = false;
  if (offFile && !parsedArgv['force-download']) {
    try {
      fs.writeFileSync(localFile, fs.readFileSync(offFile));
      copied = true;
    } catch (ex) {
      jxcore.utils.console.warn('Cannot use cached file: ' + ex);
    }

    if (copied) {
      jxtools.console.logPair('Using cached file:', offFile);
      return unpack(null, cb);
    }
  }

  // downloading if cache file is not used
  download(version, cb);
};

var checkCachedPackage = function(version) {
  var cfg = config.read();
  if (cfg.err)
    return false;
  if (!cfg.cache)
    return false;
  var cacheDir = null;
  if (cfg.cache === true)
    cacheDir = common.cacheDir;
  else {
    if (cfg.cache.readonly && cfg.cache.path && fs.existsSync(cfg.cache.path))
      cacheDir = cfg.cache.path;
  }

  if (!cacheDir)
    return false;

  var cacheFile = path.join(cacheDir, version, fname);
  return fs.existsSync(cacheFile) ? cacheFile : false;
};

var getLatestCordovaVersion = function (cb) {

  var _url = 'https://raw.githubusercontent.com/jxcore/jxcore-cordova/master/package.json';
  jxtools.http.downloadString(_url, {silent: true}, function (err, json_str) {
    if (!err) {
      var version = 'unknown';
      try {
        var json = JSON.parse(json_str);
        version = json.version;
      } catch (ex) {
        return cb("Cannot parse package.json: " + ex);
      }

      cb(false, version);
    } else {
      cb(err);
    }
  });
};

exports.run = function (cb) {

  var parsedArgv = jxcore.utils.argv.parse();

  if (fs.existsSync(localFile)) {
    var stat = fs.statSync(localFile);
    if (stat.size < 1024 * 1024)
      fs.unlinkSync(localFile);
  }

  var force = parsedArgv.force || parsedArgv['force-download'];

  if (fs.existsSync(localFile) && !force) {
    jxcore.utils.console.warn('Skipping the download, since file', fname, 'already exists.');
    jxcore.utils.console.log('If you want to force downloading, use --force option.');
    unpack(null, cb);
    return;
  }

  if (fs.existsSync(folder) && !force) {
    jxcore.utils.console.warn('Skipping the installation, since folder', dname, 'already exists.');
    jxcore.utils.console.log('If you want to force installing, use --force option.');
    return;
  }

  var plugin_installed_folder = path.join(process.cwd(), 'plugins', dname);
  if (fs.existsSync(plugin_installed_folder) && !force) {
    jxcore.utils.console.warn('Skipping the installation, since plugin is already added.');
    jxcore.utils.console.log('If you want to force installing, use --force option or remove the plugin:');
    jxcore.utils.console.log('    > cordova plugins remove ' + dname);
    return;
  }

  var argv3 = process.argv[3];
  if (argv3 && argv3.slice(0, 1) === '-')
    argv3 = null;

  if (argv3) {
    install(argv3, cb);
  } else {
    getLatestCordovaVersion(function(err, version) {
      if (err)
        jxcore.utils.console.error(err);
      else {
        jxtools.console.logPair('Latest jxcore-cordova version:', version);
        install(version, cb);
      }
    });
  }

};

<|endoftext|>


<commit_before>var semver = require('semver'),
    logger = require('../logger'),
    utils = require('../utils'),
    repository = require('../repository'),
    kansorc = require('../kansorc'),
    settings = require('../settings'),
    argParse = require('../args').parse,
    tar = require('../tar'),
    async = require('async'),
    path = require('path'),
    fs = require('fs');

exports.summary = 'Installs a package and its dependencies';

exports.usage = '' +
'kanso install [PACKAGE]\n' +
'\n' +
'The PACKAGE argument can be one of the following: \n' +
'  kanso install (with no args in a package or project dir)\n' +
'  kanso install <tarball file>\n' +
'  kanso install <tarball url>\n' +
'  kanso install <folder>\n' +
'  kanso install <name>\n' +
'  kanso install <name>@<tag>\n' +
'  kanso install <name>@<version>\n' +
'  kanso install <name>@<version range>\n' +
'\n' +
'Parameters:\n' +
'  PACKAGE    Package to install (defaults to ".")\n' +
'\n' +
'Options:\n' +
'  --force, -f    Overwrite existing packages in target directory\n' +
'  --repository   Source repository URL (otherwise uses settings in kansorc)\n' +
'  --package-dir  Output directory (defaults to "./packages")\n' +
'  --no-deps      Don\'t fetch dependencies for the package';

// set when run() is called
var OPTIONS = null;

// checked after queue.drain to see if it should exit cleanly
var ERRORS = false;

// stores the version range requirements for each package
var pkg_ranges = {};

// remembers if a package has already been removed when doing fetch -f
// otherwise, conflicting versions may overwrite each other without warning
var removed = {};

var processed = [];
var target_dir = './packages';
var repos = [];

function isProcessed(name, version) {
    for (var i = 0; i < processed.length; i++) {
        if (processed[i].name === name && processed[i].version === version) {
            return true;
        }
    }
    return false;
}

function getRanges(name) {
    var ranges = [];
    for (var k in (pkg_ranges[name] || {})) {
        ranges.push(pkg_ranges[name][k]);
    }
    return ranges;
}

function satisfiesAll(version, ranges) {
    for (var i = 0; i < ranges.length; i++) {
        if (!semver.satisfies(version, ranges[i])) {
            return false;
        }
    }
    return true;
};

function install(name, range, data, repo, parent, callback) {
    pkg_ranges[name] = pkg_ranges[name] || {};
    pkg_ranges[name][parent] = range;

    path.exists(target_dir + '/' + name, function (exists) {
        if (exists) {
            if (OPTIONS.force && !removed[name]) {
                logger.info('removing', name);
                utils.rm('-rf', target_dir + '/' + name, function (err) {
                    if (err) {
                        return callback(err);
                    }
                    removed[name] = true;
                    process.nextTick(function () {
                        install(name, range, data, repo, parent, callback);
                    });
                });
            }
            else {
                settings.load(target_dir + '/' + name, function (err, cfg) {
                    if (err) {
                        return callback(err);
                    }
                    if (!satisfiesAll(cfg.version, getRanges(name))) {
                        var range_data = '';
                        for (var k in pkg_ranges[name]) {
                            range_data += '\n' + k + ' requires: ' +
                                pkg_ranges[name][k];
                        }
                        range_data += '\n' +
                            'Currently installed version: ' + cfg.version;

                        return callback(new Error(
                            'Conflicting version requirements for ' + name +
                            range_data
                        ));
                    }
                    logger.info('skipping', name + ' (already exists)');
                    callback(null, cfg.version, cfg);
                });
            }
            return;
        }
        repository.fetch(name, range, repos, data, repo,
            function (err, tfile, cdir, v, cfg, from_cache) {
                if (err) {
                    return callback(err);
                }
                var path = target_dir + '/' + name;
                logger.info(
                    'installing',
                    name + '@' + v + (from_cache ? ' (cached)': '')
                );
                utils.ensureDir(target_dir, function (err) {
                    if (err) {
                        return callback(err);
                    }
                    utils.cp('-r', cdir, path, function (err) {
                        if (err) {
                            return callback(err);
                        }
                        callback(null, v, cfg);
                    });
                });
            }
        );
    });
}

// tries to find a satisfying package locally, otherwise checks repositories
exports.resolve = function (parent, name, range, repos, callback) {
    var pkgdir = path.join(target_dir, name);
    path.exists(path.join(pkgdir, 'kanso.json'), function (exists) {
        if (exists) {
            settings.load(pkgdir, function (err, cfg) {
                if (err) {
                    return callback(err);
                }
                if (semver.satisfies(cfg.version, range)) {
                    return callback(null, cfg.version, cfg, false);
                }
                else if (OPTIONS.force) {
                    repository.resolve(
                        name, range, repos, function (err, v, data, repo) {
                            if (err && err.notfound) {
                                return callback(new Error(
                                    'No package for ' + name + ' @ ' + range +
                                    '\nAvailable versions: ' + cfg.version
                                ));
                            }
                            else {
                                calback.apply(this, arguments);
                            }
                        }
                    );
                }
                else {
                    var range_data = '';
                    for (var k in pkg_ranges[name]) {
                        range_data += '\n' + k + ' requires: ' +
                            pkg_ranges[name][k];
                    }
                    range_data += '\n' + parent + ' requires: ' + range;
                    range_data += '\n' +
                        'Currently installed version: ' + cfg.version;

                    return callback(new Error(
                        'Conflicting version requirements for ' + name +
                        range_data
                    ));
                }
            });
        }
        else {
            repository.resolve(name, range, repos, callback);
        }
    });
};

function worker(task, callback) {
    var name = task.name;
    var range = task.range;
    var parent = task.parent;

    exports.resolve(parent, name, range, repos, function (err, v, data, repo) {
        if (err) {
            ERRORS = true;
            logger.error(err);
            return callback(err);
        }
        if (isProcessed(name, v)) {
            return callback();
        }
        processed.push({
            name: name,
            version: v,
            parent: parent
        });
        var cfg = data;
        if (repo) {
            cfg = data.versions[v];
        }
        if (cfg.dependencies && !OPTIONS['no-deps']) {
            fetchDeps(cfg.dependencies, cfg.name);
        }
        if (repo) {
            install(name, v, data, repo, parent, function (err) {
                if (err) {
                    ERRORS = true;
                    logger.error(err);
                    return callback(err);
                }
                callback();
            });
        }
        else {
            logger.info('skipping', name + ' (already exists)');
            callback();
        }
    });
}

// the concurrency of fetch requests
var concurrency = 5;
var queue = async.queue(worker, concurrency);

function fetchDeps(deps, parent) {
    Object.keys(deps).forEach(function (name) {
        queue.push({name: name, range: deps[name], parent: parent});
    });
}

exports.installDir = function (_settings, dir) {
    // install local package or project dir
    if (OPTIONS['no-deps']) {
        return logger.end();
    }
    kansorc.extend(_settings, dir + '/.kansorc', function (err, _settings) {
        settings.load(dir, function (err, cfg) {
            if (err) {
                ERRORS = true;
                return logger.error(err);
            }
            if (!cfg.dependencies) {
                logger.info('No dependencies specified');
                return logger.end();
            }
            queue.drain = function () {
                if (!ERRORS) {
                    return logger.end();
                }
            };
            if (cfg.dependencies && !OPTIONS['no-deps']) {
                fetchDeps(cfg.dependencies, cfg.name);
            }
        });
    });
};

exports.installFile = function (_settings, filename) {
    var tmp = repository.TMP_DIR + '/' + path.basename(filename);
    var tmp_extracted = repository.TMP_DIR + '/package';

    var callback = function (err) {
        var args = arguments;
        var that = this;
        utils.rm('-rf', [tmp, tmp_extracted], function (err2) {
            if (err2) {
                ERRORS = true;
                logger.error(err2);
            }
            else if (err) {
                ERRORS = true;
                logger.error(err);
            }
        });
    };

    async.series({
        tmpdir: async.apply(utils.ensureDir, repository.TMP_DIR),
        dir: async.apply(utils.ensureDir, target_dir),
        cp: function (cb) {
            if (filename === tmp) {
                // installing from a file in tmp already
                return cb();
            }
            utils.cp('-r', filename, tmp, cb);
        },
        extract: async.apply(tar.extract, tmp),
        cfg: async.apply(settings.load, tmp_extracted)
    },
    function (err, results) {
        if (err) {
            return callback(err);
        }
        var v = results.cfg.version;
        var name = results.cfg.name;
        var tpath = target_dir + '/' + name;
        path.exists(tpath, function (exists) {
            if (exists) {
                if (OPTIONS.force) {
                    logger.info('removing', name);
                    utils.rm('-rf', tpath, function (err) {
                        if (err) {
                            return callback(err);
                        }
                        process.nextTick(function () {
                            exports.installFile(_settings, filename);
                        });
                    });
                }
                else {
                    callback('"' + name + '" already exists in ' + target_dir);
                }
                return;
            }
            logger.info(
                'installing',
                name + '@' + v + ' (from file)'
            );
            utils.cp('-r', tmp_extracted, tpath, function (err) {
                if (err) {
                    return callback(err);
                }
                // note that the --packge-dir won't have changed so deps will
                // be installed in current packages dir alongside this one
                exports.installDir(_settings, tpath);
            });
        });
    });
};

exports.installName = function (_settings, name) {
    var version = 'latest';
    if (!name) {
        ERRORS = true;
        return logger.error('No package name specified');
    }
    if (name.indexOf('@') !== -1) {
        var parts = name.split('@');
        name = parts[0];
        version = parts.slice(1).join('@');
    }
    var deps = {};
    deps[name] = version || null;

    queue.drain = function () {
        if (!ERRORS) {
            return logger.end();
        }
    };
    fetchDeps(deps, null);
};

exports.installURL = function (_settings, target) {
    repository.download(target, function (err, filename) {
        if (err) {
            ERRORS = true;
            return logger.error(err);
        }
        exports.installFile(_settings, filename);
    });
};

exports.run = function (_settings, args) {
    var a = argParse(args, {
        'repository': {match: '--repository', value: true},
        'force': {match: ['-f', '--force']},
        'package-dir': {match: '--package-dir', value: true},
        'no-deps': {match: '--no-deps'}
    });

    // make sure package-dir is relative to current dir nor package paths

    OPTIONS = a.options;

    var pkg = a.positional[0] || '.';

    repos = _settings.repositories;
    if (a.options.repository) {
        repos = [a.options.repository];
    }

    target_dir = a.options['package-dir'];

    if (/^https?:\/\//.test(pkg)) {
        target_dir = target_dir || utils.abspath('packages');
        logger.info('installing from URL', pkg);
        return exports.installURL(_settings, pkg);
    }
    fs.stat(pkg, function (err, stats) {
        if (err) {
            // may not be a file
            target_dir = target_dir || utils.abspath('packages');
            logger.info('installing from repositories', pkg);
            return exports.installName(_settings, pkg);
        }
        if (stats.isDirectory()) {
            target_dir = target_dir || utils.abspath('packages', pkg);
            logger.info('installing from directory', pkg);
            return exports.installDir(_settings, pkg);
        }
        else if (stats.isFile()) {
            target_dir = target_dir || utils.abspath('packages');
            logger.info('installing from local file', pkg);
            return exports.installFile(_settings, pkg);
        }
        else {
            throw new Error('Unknown install target: ' + pkg);
        }
    });
};
<commit_msg>Update lib/commands/install.js<commit_after>var semver = require('semver'),
    logger = require('../logger'),
    utils = require('../utils'),
    repository = require('../repository'),
    kansorc = require('../kansorc'),
    settings = require('../settings'),
    argParse = require('../args').parse,
    tar = require('../tar'),
    async = require('async'),
    path = require('path'),
    fs = require('fs');

exports.summary = 'Installs a package and its dependencies';

exports.usage = '' +
'kanso install [PACKAGE]\n' +
'\n' +
'The PACKAGE argument can be one of the following: \n' +
'  kanso install (with no args in a package or project dir)\n' +
'  kanso install <tarball file>\n' +
'  kanso install <tarball url>\n' +
'  kanso install <folder>\n' +
'  kanso install <name>\n' +
'  kanso install <name>@<tag>\n' +
'  kanso install <name>@<version>\n' +
'  kanso install <name>@<version range>\n' +
'\n' +
'Parameters:\n' +
'  PACKAGE    Package to install (defaults to ".")\n' +
'\n' +
'Options:\n' +
'  --force, -f    Overwrite existing packages in target directory\n' +
'  --repository   Source repository URL (otherwise uses settings in kansorc)\n' +
'  --package-dir  Output directory (defaults to "./packages")\n' +
'  --no-deps      Don\'t fetch dependencies for the package';

// set when run() is called
var OPTIONS = null;

// checked after queue.drain to see if it should exit cleanly
var ERRORS = false;

// stores the version range requirements for each package
var pkg_ranges = {};

// remembers if a package has already been removed when doing fetch -f
// otherwise, conflicting versions may overwrite each other without warning
var removed = {};

var processed = [];
var target_dir = './packages';
var repos = [];

function isProcessed(name, version) {
    for (var i = 0; i < processed.length; i++) {
        if (processed[i].name === name && processed[i].version === version) {
            return true;
        }
    }
    return false;
}

function getRanges(name) {
    var ranges = [];
    for (var k in (pkg_ranges[name] || {})) {
        ranges.push(pkg_ranges[name][k]);
    }
    return ranges;
}

function satisfiesAll(version, ranges) {
    for (var i = 0; i < ranges.length; i++) {
        if (!semver.satisfies(version, ranges[i])) {
            return false;
        }
    }
    return true;
};

function install(name, range, data, repo, parent, callback) {
    pkg_ranges[name] = pkg_ranges[name] || {};
    pkg_ranges[name][parent] = range;

    path.exists(target_dir + '/' + name, function (exists) {
        if (exists) {
            if (OPTIONS.force && !removed[name]) {
                logger.info('removing', name);
                utils.rm('-rf', target_dir + '/' + name, function (err) {
                    if (err) {
                        return callback(err);
                    }
                    removed[name] = true;
                    process.nextTick(function () {
                        install(name, range, data, repo, parent, callback);
                    });
                });
            }
            else {
                settings.load(target_dir + '/' + name, function (err, cfg) {
                    if (err) {
                        return callback(err);
                    }
                    if (!satisfiesAll(cfg.version, getRanges(name))) {
                        var range_data = '';
                        for (var k in pkg_ranges[name]) {
                            range_data += '\n' + k + ' requires: ' +
                                pkg_ranges[name][k];
                        }
                        range_data += '\n' +
                            'Currently installed version: ' + cfg.version;

                        return callback(new Error(
                            'Conflicting version requirements for ' + name +
                            range_data
                        ));
                    }
                    logger.info('skipping', name + ' (already exists)');
                    callback(null, cfg.version, cfg);
                });
            }
            return;
        }
        repository.fetch(name, range, repos, data, repo,
            function (err, tfile, cdir, v, cfg, from_cache) {
                if (err) {
                    return callback(err);
                }
                var path = target_dir + '/' + name;
                logger.info(
                    'installing',
                    name + '@' + v + (from_cache ? ' (cached)': '')
                );
                utils.ensureDir(target_dir, function (err) {
                    if (err) {
                        return callback(err);
                    }
                    utils.cp('-r', cdir, path, function (err) {
                        if (err) {
                            return callback(err);
                        }
                        callback(null, v, cfg);
                    });
                });
            }
        );
    });
}

// tries to find a satisfying package locally, otherwise checks repositories
exports.resolve = function (parent, name, range, repos, callback) {
    var pkgdir = path.join(target_dir, name);
    path.exists(path.join(pkgdir, 'kanso.json'), function (exists) {
        if (exists) {
            settings.load(pkgdir, function (err, cfg) {
                if (err) {
                    return callback(err);
                }
                if (semver.satisfies(cfg.version, range)) {
                    return callback(null, cfg.version, cfg, false);
                }
                else if (OPTIONS.force) {
                    repository.resolve(
                        name, range, repos, function (err, v, data, repo) {
                            if (err && err.notfound) {
                                return callback(new Error(
                                    'No package for ' + name + ' @ ' + range +
                                    '\nAvailable versions: ' + cfg.version
                                ));
                            }
                            else {
                                callback.apply(this, arguments);
                            }
                        }
                    );
                }
                else {
                    var range_data = '';
                    for (var k in pkg_ranges[name]) {
                        range_data += '\n' + k + ' requires: ' +
                            pkg_ranges[name][k];
                    }
                    range_data += '\n' + parent + ' requires: ' + range;
                    range_data += '\n' +
                        'Currently installed version: ' + cfg.version;

                    return callback(new Error(
                        'Conflicting version requirements for ' + name +
                        range_data
                    ));
                }
            });
        }
        else {
            repository.resolve(name, range, repos, callback);
        }
    });
};

function worker(task, callback) {
    var name = task.name;
    var range = task.range;
    var parent = task.parent;

    exports.resolve(parent, name, range, repos, function (err, v, data, repo) {
        if (err) {
            ERRORS = true;
            logger.error(err);
            return callback(err);
        }
        if (isProcessed(name, v)) {
            return callback();
        }
        processed.push({
            name: name,
            version: v,
            parent: parent
        });
        var cfg = data;
        if (repo) {
            cfg = data.versions[v];
        }
        if (cfg.dependencies && !OPTIONS['no-deps']) {
            fetchDeps(cfg.dependencies, cfg.name);
        }
        if (repo) {
            install(name, v, data, repo, parent, function (err) {
                if (err) {
                    ERRORS = true;
                    logger.error(err);
                    return callback(err);
                }
                callback();
            });
        }
        else {
            logger.info('skipping', name + ' (already exists)');
            callback();
        }
    });
}

// the concurrency of fetch requests
var concurrency = 5;
var queue = async.queue(worker, concurrency);

function fetchDeps(deps, parent) {
    Object.keys(deps).forEach(function (name) {
        queue.push({name: name, range: deps[name], parent: parent});
    });
}

exports.installDir = function (_settings, dir) {
    // install local package or project dir
    if (OPTIONS['no-deps']) {
        return logger.end();
    }
    kansorc.extend(_settings, dir + '/.kansorc', function (err, _settings) {
        settings.load(dir, function (err, cfg) {
            if (err) {
                ERRORS = true;
                return logger.error(err);
            }
            if (!cfg.dependencies) {
                logger.info('No dependencies specified');
                return logger.end();
            }
            queue.drain = function () {
                if (!ERRORS) {
                    return logger.end();
                }
            };
            if (cfg.dependencies && !OPTIONS['no-deps']) {
                fetchDeps(cfg.dependencies, cfg.name);
            }
        });
    });
};

exports.installFile = function (_settings, filename) {
    var tmp = repository.TMP_DIR + '/' + path.basename(filename);
    var tmp_extracted = repository.TMP_DIR + '/package';

    var callback = function (err) {
        var args = arguments;
        var that = this;
        utils.rm('-rf', [tmp, tmp_extracted], function (err2) {
            if (err2) {
                ERRORS = true;
                logger.error(err2);
            }
            else if (err) {
                ERRORS = true;
                logger.error(err);
            }
        });
    };

    async.series({
        tmpdir: async.apply(utils.ensureDir, repository.TMP_DIR),
        dir: async.apply(utils.ensureDir, target_dir),
        cp: function (cb) {
            if (filename === tmp) {
                // installing from a file in tmp already
                return cb();
            }
            utils.cp('-r', filename, tmp, cb);
        },
        extract: async.apply(tar.extract, tmp),
        cfg: async.apply(settings.load, tmp_extracted)
    },
    function (err, results) {
        if (err) {
            return callback(err);
        }
        var v = results.cfg.version;
        var name = results.cfg.name;
        var tpath = target_dir + '/' + name;
        path.exists(tpath, function (exists) {
            if (exists) {
                if (OPTIONS.force) {
                    logger.info('removing', name);
                    utils.rm('-rf', tpath, function (err) {
                        if (err) {
                            return callback(err);
                        }
                        process.nextTick(function () {
                            exports.installFile(_settings, filename);
                        });
                    });
                }
                else {
                    callback('"' + name + '" already exists in ' + target_dir);
                }
                return;
            }
            logger.info(
                'installing',
                name + '@' + v + ' (from file)'
            );
            utils.cp('-r', tmp_extracted, tpath, function (err) {
                if (err) {
                    return callback(err);
                }
                // note that the --packge-dir won't have changed so deps will
                // be installed in current packages dir alongside this one
                exports.installDir(_settings, tpath);
            });
        });
    });
};

exports.installName = function (_settings, name) {
    var version = 'latest';
    if (!name) {
        ERRORS = true;
        return logger.error('No package name specified');
    }
    if (name.indexOf('@') !== -1) {
        var parts = name.split('@');
        name = parts[0];
        version = parts.slice(1).join('@');
    }
    var deps = {};
    deps[name] = version || null;

    queue.drain = function () {
        if (!ERRORS) {
            return logger.end();
        }
    };
    fetchDeps(deps, null);
};

exports.installURL = function (_settings, target) {
    repository.download(target, function (err, filename) {
        if (err) {
            ERRORS = true;
            return logger.error(err);
        }
        exports.installFile(_settings, filename);
    });
};

exports.run = function (_settings, args) {
    var a = argParse(args, {
        'repository': {match: '--repository', value: true},
        'force': {match: ['-f', '--force']},
        'package-dir': {match: '--package-dir', value: true},
        'no-deps': {match: '--no-deps'}
    });

    // make sure package-dir is relative to current dir nor package paths

    OPTIONS = a.options;

    var pkg = a.positional[0] || '.';

    repos = _settings.repositories;
    if (a.options.repository) {
        repos = [a.options.repository];
    }

    target_dir = a.options['package-dir'];

    if (/^https?:\/\//.test(pkg)) {
        target_dir = target_dir || utils.abspath('packages');
        logger.info('installing from URL', pkg);
        return exports.installURL(_settings, pkg);
    }
    fs.stat(pkg, function (err, stats) {
        if (err) {
            // may not be a file
            target_dir = target_dir || utils.abspath('packages');
            logger.info('installing from repositories', pkg);
            return exports.installName(_settings, pkg);
        }
        if (stats.isDirectory()) {
            target_dir = target_dir || utils.abspath('packages', pkg);
            logger.info('installing from directory', pkg);
            return exports.installDir(_settings, pkg);
        }
        else if (stats.isFile()) {
            target_dir = target_dir || utils.abspath('packages');
            logger.info('installing from local file', pkg);
            return exports.installFile(_settings, pkg);
        }
        else {
            throw new Error('Unknown install target: ' + pkg);
        }
    });
};
<|endoftext|>


<commit_before>/* eslint prefer-destructuring: ["error", {AssignmentExpression: {array: true}}] */

const path = require('path');
const readline = require('readline');
const chalk = require('chalk');
const publisher = require('apex-publish-static-files');
const util = require('../util/util');
const validations = require('../util/validations');
const launch = require('./launch');

// Validates if an object is empty (true), otherwise (false)
const getAppID = function(appUrl) {
	const paramString = appUrl.substring(appUrl.indexOf('f?p=') + 4).split(':');
	return paramString[0];
};

module.exports = function() {
	const config = util.getConfig();

	validations.publish(config);

	// Compile and publish files
	const launchPublish = async function(password) {
		launch(async () => {
			console.log(chalk.cyan('...Now'), chalk.cyan.bold('publishing!'));

			const publish = function() {
				publisher.publish({
					sqlclPath: config.publish.path,
					connectString: `${config.publish.username}/${password}@${
						config.publish.connectionString
					}`,
					directory: path.resolve(config.distFolder),
					appID: getAppID(config.appUrl),
					destination: config.publish.destination,
					pluginName: config.publish.pluginName
				});
			};

			if (config.mode === 'basic') {
				publish();
			} else {
				const build = require(path.resolve(process.cwd(), 'nitro', 'build-phases.js'));

				const lintValid = await build.lint();

				if (lintValid) {
					await build.bundleProd();
					publish();
				}
			}
		});
	};

	// Validates if the srcFolder is valid
	if (validations.isSrcFolderValid(config)) {
		// If the password is not provided, let's prompt it to the user
		if (config.publish.connectionType === 'basic' && config.publish.password === undefined) {
			const rl = readline.createInterface({
				input: process.stdin,
				output: process.stdout
			});

			rl.question('Enter your database schema password: ', answer => {
				launchPublish(answer);
				rl.close();
			});
		} else {
			launchPublish(config.publish.password);
		}
	}
};
<commit_msg>xo fixes<commit_after>/* eslint prefer-destructuring: ["error", {AssignmentExpression: {array: true}}] */

const path = require('path');
const readline = require('readline');
const chalk = require('chalk');
const publisher = require('apex-publish-static-files');
const util = require('../util/util');
const validations = require('../util/validations');
const launch = require('./launch');

// Validates if an object is empty (true), otherwise (false)
const getAppID = function (appUrl) {
	const paramString = appUrl.substring(appUrl.indexOf('f?p=') + 4).split(':');
	return paramString[0];
};

module.exports = function () {
	const config = util.getConfig();

	validations.publish(config);

	// Compile and publish files
	const launchPublish = async function (password) {
		launch(async () => {
			console.log(chalk.cyan('...Now'), chalk.cyan.bold('publishing!'));

			const publish = function () {
				publisher.publish({
					sqlclPath: config.publish.path,
					connectString: `${config.publish.username}/${password}@${
						config.publish.connectionString
					}`,
					directory: path.resolve(config.distFolder),
					appID: getAppID(config.appUrl),
					destination: config.publish.destination,
					pluginName: config.publish.pluginName
				});
			};

			if (config.mode === 'basic') {
				publish();
			} else {
				const build = require(path.resolve(process.cwd(), 'nitro', 'build-phases.js'));

				const lintValid = await build.lint();

				if (lintValid) {
					await build.bundleProd();
					publish();
				}
			}
		});
	};

	// Validates if the srcFolder is valid
	if (validations.isSrcFolderValid(config)) {
		// If the password is not provided, let's prompt it to the user
		if (config.publish.connectionType === 'basic' && config.publish.password === undefined) {
			const rl = readline.createInterface({
				input: process.stdin,
				output: process.stdout
			});

			rl.question('Enter your database schema password: ', answer => {
				launchPublish(answer);
				rl.close();
			});
		} else {
			launchPublish(config.publish.password);
		}
	}
};
<|endoftext|>


<commit_before>const is = require('@sindresorhus/is');
const later = require('later');
const deepcopy = require('deepcopy');
const options = require('./definitions').getOptions();

let optionTypes;

module.exports = {
  migrateConfig,
};

const removedOptions = [
  'maintainYarnLock',
  'yarnCacheFolder',
  'yarnMaintenanceBranchName',
  'yarnMaintenanceCommitMessage',
  'yarnMaintenancePrTitle',
  'yarnMaintenancePrBody',
  'groupBranchName',
  'groupBranchName',
  'groupCommitMessage',
  'groupPrTitle',
  'groupPrBody',
];

// Returns a migrated config
function migrateConfig(config) {
  try {
    if (!optionTypes) {
      optionTypes = {};
      options.forEach(option => {
        optionTypes[option.name] = option.type;
      });
    }
    let isMigrated = false;
    const migratedConfig = deepcopy(config);
    const depTypes = [
      'dependencies',
      'devDependencies',
      'optionalDependencies',
      'peerDependencies',
    ];
    for (const [key, val] of Object.entries(config)) {
      if (removedOptions.includes(key)) {
        isMigrated = true;
        delete migratedConfig[key];
      } else if (key === 'pathRules') {
        isMigrated = true;
        if (is.array(val)) {
          migratedConfig.packageRules = migratedConfig.packageRules || [];
          const migratedPathRules = migratedConfig.pathRules.map(
            p => migrateConfig(p).migratedConfig
          );
          migratedConfig.packageRules = migratedPathRules.concat(
            migratedConfig.packageRules
          );
        }
        delete migratedConfig.pathRules;
      } else if (key === 'packageFiles' && is.array(val)) {
        isMigrated = true;
        const fileList = [];
        for (const packageFile of val) {
          if (is.object(packageFile) && !is.array(packageFile)) {
            fileList.push(packageFile.packageFile);
            if (Object.keys(packageFile).length > 1) {
              migratedConfig.packageRules = migratedConfig.packageRules || [];
              const payload = migrateConfig(packageFile).migratedConfig;
              for (const subrule of payload.packageRules || []) {
                subrule.paths = [packageFile.packageFile];
                migratedConfig.packageRules.push(subrule);
              }
              delete payload.packageFile;
              delete payload.packageRules;
              if (Object.keys(payload).length) {
                migratedConfig.packageRules.push({
                  ...payload,
                  paths: [packageFile.packageFile],
                });
              }
            }
          } else {
            fileList.push(packageFile);
          }
        }
        migratedConfig.includePaths = fileList;
        delete migratedConfig.packageFiles;
      } else if (depTypes.includes(key)) {
        isMigrated = true;
        migratedConfig.packageRules = migratedConfig.packageRules || [];
        const depTypePackageRule = migrateConfig(val).migratedConfig;
        depTypePackageRule.depTypeList = [key];
        delete depTypePackageRule.packageRules;
        migratedConfig.packageRules.push(depTypePackageRule);
        delete migratedConfig[key];
      } else if (key === 'pinVersions') {
        isMigrated = true;
        delete migratedConfig.pinVersions;
        if (val === true) {
          migratedConfig.rangeStrategy = 'pin';
        } else if (val === false) {
          migratedConfig.rangeStrategy = 'replace';
        }
      } else if (key === 'upgradeInRange') {
        isMigrated = true;
        delete migratedConfig.upgradeInRange;
        if (val === true) {
          migratedConfig.rangeStrategy = 'bump';
        }
      } else if (key === 'versionStrategy') {
        isMigrated = true;
        delete migratedConfig.versionStrategy;
        if (val === 'widen') {
          migratedConfig.rangeStrategy = 'widen';
        }
      } else if (key === 'semanticPrefix') {
        isMigrated = true;
        delete migratedConfig.semanticPrefix;
        let [text] = val.split(':');
        text = text.split('(');
        [migratedConfig.semanticCommitType] = text;
        if (text.length > 1) {
          [migratedConfig.semanticCommitScope] = text[1].split(')');
        } else {
          migratedConfig.semanticCommitScope = null;
        }
      } else if (key === 'extends' && is.array(val)) {
        for (let i = 0; i < val.length; i += 1) {
          if (val[i] === 'config:application' || val[i] === ':js-app') {
            isMigrated = true;
            migratedConfig.extends[i] = 'config:js-app';
          } else if (val[i] === ':library' || val[i] === 'config:library') {
            isMigrated = true;
            migratedConfig.extends[i] = 'config:js-lib';
          }
        }
      } else if (key === 'automergeType' && val.startsWith('branch-')) {
        isMigrated = true;
        migratedConfig.automergeType = 'branch';
      } else if (key === 'automergeMinor') {
        isMigrated = true;
        migratedConfig.minor = migratedConfig.minor || {};
        migratedConfig.minor.automerge = val == true; // eslint-disable-line eqeqeq
        delete migratedConfig[key];
      } else if (key === 'automergeMajor') {
        isMigrated = true;
        migratedConfig.major = migratedConfig.major || {};
        migratedConfig.major.automerge = val == true; // eslint-disable-line eqeqeq
        delete migratedConfig[key];
      } else if (key === 'multipleMajorPrs') {
        isMigrated = true;
        delete migratedConfig.multipleMajorPrs;
        migratedConfig.separateMultipleMajor = val;
      } else if (key === 'separateMajorReleases') {
        isMigrated = true;
        delete migratedConfig.separateMultipleMajor;
        migratedConfig.separateMajorMinor = val;
      } else if (key === 'separatePatchReleases') {
        isMigrated = true;
        delete migratedConfig.separatePatchReleases;
        migratedConfig.separateMinorPatch = val;
      } else if (key === 'automergePatch') {
        isMigrated = true;
        migratedConfig.patch = migratedConfig.patch || {};
        migratedConfig.patch.automerge = val == true; // eslint-disable-line eqeqeq
        delete migratedConfig[key];
      } else if (key === 'ignoreNodeModules') {
        isMigrated = true;
        delete migratedConfig.ignoreNodeModules;
        migratedConfig.ignorePaths = val ? ['node_modules/'] : [];
      } else if (
        key === 'automerge' &&
        is.string(val) &&
        ['none', 'patch', 'minor', 'any'].includes(val)
      ) {
        delete migratedConfig.automerge;
        isMigrated = true;
        if (val === 'none') {
          migratedConfig.automerge = false;
        } else if (val === 'patch') {
          migratedConfig.patch = migratedConfig.patch || {};
          migratedConfig.patch.automerge = true;
          migratedConfig.minor = migratedConfig.minor || {};
          migratedConfig.minor.automerge = false;
          migratedConfig.major = migratedConfig.major || {};
          migratedConfig.major.automerge = false;
        } else if (val === 'minor') {
          migratedConfig.minor = migratedConfig.minor || {};
          migratedConfig.minor.automerge = true;
          migratedConfig.major = migratedConfig.major || {};
          migratedConfig.major.automerge = false;
        } else if (val === 'any') {
          migratedConfig.automerge = true;
        }
      } else if (key === 'packages') {
        isMigrated = true;
        migratedConfig.packageRules = migratedConfig.packageRules || [];
        migratedConfig.packageRules = migratedConfig.packageRules.concat(
          migratedConfig.packages.map(p => migrateConfig(p).migratedConfig)
        );
        delete migratedConfig.packages;
      } else if (key === 'excludedPackageNames') {
        isMigrated = true;
        migratedConfig.excludePackageNames = val;
        delete migratedConfig.excludedPackageNames;
      } else if (key === 'packageName') {
        isMigrated = true;
        migratedConfig.packageNames = [val];
        delete migratedConfig.packageName;
      } else if (key === 'packagePattern') {
        isMigrated = true;
        migratedConfig.packagePatterns = [val];
        delete migratedConfig.packagePattern;
      } else if (key === 'baseBranch') {
        isMigrated = true;
        migratedConfig.baseBranches = is.array(val) ? val : [val];
        delete migratedConfig.baseBranch;
      } else if (key === 'schedule' && !val) {
        isMigrated = true;
        migratedConfig.schedule = [];
      } else if (key === 'schedule') {
        // massage to array first
        const schedules = is.string(val) ? [val] : val;
        // split 'and'
        for (let i = 0; i < schedules.length; i += 1) {
          if (
            schedules[i].includes(' and ') &&
            schedules[i].includes('before ') &&
            schedules[i].includes('after ')
          ) {
            const parsedSchedule = later.parse.text(
              // We need to massage short hours first before we can parse it
              schedules[i].replace(/( \d?\d)((a|p)m)/g, '$1:00$2')
            ).schedules[0];
            // Only migrate if the after time is greater than before, e.g. "after 10pm and before 5am"
            if (
              parsedSchedule &&
              parsedSchedule.t_a[0] > parsedSchedule.t_b[0]
            ) {
              isMigrated = true;
              const toSplit = schedules[i];
              schedules[i] = toSplit
                .replace(
                  /^(after|before) (.*?) and (after|before) (.*?)( |$)(.*)/,
                  '$1 $2 $6'
                )
                .trim();
              schedules.push(
                toSplit
                  .replace(
                    /^(after|before) (.*?) and (after|before) (.*?)( |$)(.*)/,
                    '$3 $4 $6'
                  )
                  .trim()
              );
            }
          }
        }
        for (let i = 0; i < schedules.length; i += 1) {
          if (schedules[i].includes('on the last day of the month')) {
            isMigrated = true;
            schedules[i] = schedules[i].replace(
              'on the last day of the month',
              'on the first day of the month'
            );
          }
          if (schedules[i].includes('on every weekday')) {
            isMigrated = true;
            schedules[i] = schedules[i].replace(
              'on every weekday',
              'every weekday'
            );
          }
          if (schedules[i].endsWith(' every day')) {
            isMigrated = true;
            schedules[i] = schedules[i].replace(' every day', '');
          }
          if (
            schedules[i].match(
              /every (mon|tues|wednes|thurs|fri|satur|sun)day$/
            )
          ) {
            isMigrated = true;
            schedules[i] = schedules[i].replace(/every ([a-z]*day)$/, 'on $1');
          }
          if (schedules[i].endsWith('days')) {
            isMigrated = true;
            schedules[i] = schedules[i].replace('days', 'day');
          }
        }
        if (isMigrated) {
          if (is.string(val) && schedules.length === 1) {
            [migratedConfig.schedule] = schedules;
          } else {
            migratedConfig.schedule = schedules;
          }
        }
      } else if (is.string(val) && val.startsWith('{{semanticPrefix}}')) {
        isMigrated = true;
        migratedConfig[key] = val.replace(
          '{{semanticPrefix}}',
          '{{#if semanticCommitType}}{{semanticCommitType}}{{#if semanticCommitScope}}({{semanticCommitScope}}){{/if}}: {{/if}}'
        );
      } else if (key === 'depTypes' && is.array(val)) {
        val.forEach(depType => {
          if (is.object(depType) && !is.array(depType)) {
            const depTypeName = depType.depType;
            if (depTypeName) {
              migratedConfig.packageRules = migratedConfig.packageRules || [];
              const newPackageRule = migrateConfig(depType).migratedConfig;
              delete newPackageRule.depType;
              newPackageRule.depTypeList = [depTypeName];
              migratedConfig.packageRules.push(newPackageRule);
            }
          }
        });
        isMigrated = true;
        delete migratedConfig.depTypes;
      } else if (optionTypes[key] === 'json' && is.boolean(val)) {
        isMigrated = true;
        migratedConfig[key] = { enabled: val };
      } else if (optionTypes[key] === 'boolean') {
        if (val === 'true') {
          migratedConfig[key] = true;
        } else if (val === 'false') {
          migratedConfig[key] = false;
        }
      } else if (
        optionTypes[key] === 'string' &&
        is.array(val) &&
        val.length === 1
      ) {
        migratedConfig[key] = `${val[0]}`;
      } else if (key === 'node' && val.enabled === true) {
        isMigrated = true;
        delete migratedConfig.node.enabled;
        migratedConfig.travis = migratedConfig.travis || {};
        migratedConfig.travis.enabled = true;
        if (!Object.keys(migratedConfig.node).length) {
          delete migratedConfig.node;
        } else {
          const subMigrate = migrateConfig(migratedConfig.node);
          migratedConfig.node = subMigrate.migratedConfig;
        }
      } else if (is.array(val)) {
        const newArray = [];
        for (const item of migratedConfig[key]) {
          if (is.object(item) && !is.array(item)) {
            const arrMigrate = migrateConfig(item);
            newArray.push(arrMigrate.migratedConfig);
            if (arrMigrate.isMigrated) {
              isMigrated = true;
            }
          } else {
            newArray.push(item);
          }
        }
        migratedConfig[key] = newArray;
      } else if (is.object(val)) {
        const subMigrate = migrateConfig(migratedConfig[key]);
        if (subMigrate.isMigrated) {
          isMigrated = true;
          migratedConfig[key] = subMigrate.migratedConfig;
        }
      } else if (
        (key === 'prBody' || key.startsWith('commitMessage')) &&
        (val.includes('currentVersion') || val.includes('newVersion'))
      ) {
        isMigrated = true;
        migratedConfig[key] = val
          .replace(/currentVersion/g, 'currentValue')
          .replace(/newVersion/g, 'newValue')
          .replace(/newValueMajor/g, 'newMajor')
          .replace(/newValueMinor/g, 'newMinor');
      }
    }
    return { isMigrated, migratedConfig };
  } catch (err) /* istanbul ignore next */ {
    logger.debug({ config }, 'migrateConfig() error');
    throw err;
  }
}
<commit_msg>fix: scheduler parse check<commit_after>const is = require('@sindresorhus/is');
const later = require('later');
const deepcopy = require('deepcopy');
const options = require('./definitions').getOptions();

let optionTypes;

module.exports = {
  migrateConfig,
};

const removedOptions = [
  'maintainYarnLock',
  'yarnCacheFolder',
  'yarnMaintenanceBranchName',
  'yarnMaintenanceCommitMessage',
  'yarnMaintenancePrTitle',
  'yarnMaintenancePrBody',
  'groupBranchName',
  'groupBranchName',
  'groupCommitMessage',
  'groupPrTitle',
  'groupPrBody',
];

// Returns a migrated config
function migrateConfig(config) {
  try {
    if (!optionTypes) {
      optionTypes = {};
      options.forEach(option => {
        optionTypes[option.name] = option.type;
      });
    }
    let isMigrated = false;
    const migratedConfig = deepcopy(config);
    const depTypes = [
      'dependencies',
      'devDependencies',
      'optionalDependencies',
      'peerDependencies',
    ];
    for (const [key, val] of Object.entries(config)) {
      if (removedOptions.includes(key)) {
        isMigrated = true;
        delete migratedConfig[key];
      } else if (key === 'pathRules') {
        isMigrated = true;
        if (is.array(val)) {
          migratedConfig.packageRules = migratedConfig.packageRules || [];
          const migratedPathRules = migratedConfig.pathRules.map(
            p => migrateConfig(p).migratedConfig
          );
          migratedConfig.packageRules = migratedPathRules.concat(
            migratedConfig.packageRules
          );
        }
        delete migratedConfig.pathRules;
      } else if (key === 'packageFiles' && is.array(val)) {
        isMigrated = true;
        const fileList = [];
        for (const packageFile of val) {
          if (is.object(packageFile) && !is.array(packageFile)) {
            fileList.push(packageFile.packageFile);
            if (Object.keys(packageFile).length > 1) {
              migratedConfig.packageRules = migratedConfig.packageRules || [];
              const payload = migrateConfig(packageFile).migratedConfig;
              for (const subrule of payload.packageRules || []) {
                subrule.paths = [packageFile.packageFile];
                migratedConfig.packageRules.push(subrule);
              }
              delete payload.packageFile;
              delete payload.packageRules;
              if (Object.keys(payload).length) {
                migratedConfig.packageRules.push({
                  ...payload,
                  paths: [packageFile.packageFile],
                });
              }
            }
          } else {
            fileList.push(packageFile);
          }
        }
        migratedConfig.includePaths = fileList;
        delete migratedConfig.packageFiles;
      } else if (depTypes.includes(key)) {
        isMigrated = true;
        migratedConfig.packageRules = migratedConfig.packageRules || [];
        const depTypePackageRule = migrateConfig(val).migratedConfig;
        depTypePackageRule.depTypeList = [key];
        delete depTypePackageRule.packageRules;
        migratedConfig.packageRules.push(depTypePackageRule);
        delete migratedConfig[key];
      } else if (key === 'pinVersions') {
        isMigrated = true;
        delete migratedConfig.pinVersions;
        if (val === true) {
          migratedConfig.rangeStrategy = 'pin';
        } else if (val === false) {
          migratedConfig.rangeStrategy = 'replace';
        }
      } else if (key === 'upgradeInRange') {
        isMigrated = true;
        delete migratedConfig.upgradeInRange;
        if (val === true) {
          migratedConfig.rangeStrategy = 'bump';
        }
      } else if (key === 'versionStrategy') {
        isMigrated = true;
        delete migratedConfig.versionStrategy;
        if (val === 'widen') {
          migratedConfig.rangeStrategy = 'widen';
        }
      } else if (key === 'semanticPrefix') {
        isMigrated = true;
        delete migratedConfig.semanticPrefix;
        let [text] = val.split(':');
        text = text.split('(');
        [migratedConfig.semanticCommitType] = text;
        if (text.length > 1) {
          [migratedConfig.semanticCommitScope] = text[1].split(')');
        } else {
          migratedConfig.semanticCommitScope = null;
        }
      } else if (key === 'extends' && is.array(val)) {
        for (let i = 0; i < val.length; i += 1) {
          if (val[i] === 'config:application' || val[i] === ':js-app') {
            isMigrated = true;
            migratedConfig.extends[i] = 'config:js-app';
          } else if (val[i] === ':library' || val[i] === 'config:library') {
            isMigrated = true;
            migratedConfig.extends[i] = 'config:js-lib';
          }
        }
      } else if (key === 'automergeType' && val.startsWith('branch-')) {
        isMigrated = true;
        migratedConfig.automergeType = 'branch';
      } else if (key === 'automergeMinor') {
        isMigrated = true;
        migratedConfig.minor = migratedConfig.minor || {};
        migratedConfig.minor.automerge = val == true; // eslint-disable-line eqeqeq
        delete migratedConfig[key];
      } else if (key === 'automergeMajor') {
        isMigrated = true;
        migratedConfig.major = migratedConfig.major || {};
        migratedConfig.major.automerge = val == true; // eslint-disable-line eqeqeq
        delete migratedConfig[key];
      } else if (key === 'multipleMajorPrs') {
        isMigrated = true;
        delete migratedConfig.multipleMajorPrs;
        migratedConfig.separateMultipleMajor = val;
      } else if (key === 'separateMajorReleases') {
        isMigrated = true;
        delete migratedConfig.separateMultipleMajor;
        migratedConfig.separateMajorMinor = val;
      } else if (key === 'separatePatchReleases') {
        isMigrated = true;
        delete migratedConfig.separatePatchReleases;
        migratedConfig.separateMinorPatch = val;
      } else if (key === 'automergePatch') {
        isMigrated = true;
        migratedConfig.patch = migratedConfig.patch || {};
        migratedConfig.patch.automerge = val == true; // eslint-disable-line eqeqeq
        delete migratedConfig[key];
      } else if (key === 'ignoreNodeModules') {
        isMigrated = true;
        delete migratedConfig.ignoreNodeModules;
        migratedConfig.ignorePaths = val ? ['node_modules/'] : [];
      } else if (
        key === 'automerge' &&
        is.string(val) &&
        ['none', 'patch', 'minor', 'any'].includes(val)
      ) {
        delete migratedConfig.automerge;
        isMigrated = true;
        if (val === 'none') {
          migratedConfig.automerge = false;
        } else if (val === 'patch') {
          migratedConfig.patch = migratedConfig.patch || {};
          migratedConfig.patch.automerge = true;
          migratedConfig.minor = migratedConfig.minor || {};
          migratedConfig.minor.automerge = false;
          migratedConfig.major = migratedConfig.major || {};
          migratedConfig.major.automerge = false;
        } else if (val === 'minor') {
          migratedConfig.minor = migratedConfig.minor || {};
          migratedConfig.minor.automerge = true;
          migratedConfig.major = migratedConfig.major || {};
          migratedConfig.major.automerge = false;
        } else if (val === 'any') {
          migratedConfig.automerge = true;
        }
      } else if (key === 'packages') {
        isMigrated = true;
        migratedConfig.packageRules = migratedConfig.packageRules || [];
        migratedConfig.packageRules = migratedConfig.packageRules.concat(
          migratedConfig.packages.map(p => migrateConfig(p).migratedConfig)
        );
        delete migratedConfig.packages;
      } else if (key === 'excludedPackageNames') {
        isMigrated = true;
        migratedConfig.excludePackageNames = val;
        delete migratedConfig.excludedPackageNames;
      } else if (key === 'packageName') {
        isMigrated = true;
        migratedConfig.packageNames = [val];
        delete migratedConfig.packageName;
      } else if (key === 'packagePattern') {
        isMigrated = true;
        migratedConfig.packagePatterns = [val];
        delete migratedConfig.packagePattern;
      } else if (key === 'baseBranch') {
        isMigrated = true;
        migratedConfig.baseBranches = is.array(val) ? val : [val];
        delete migratedConfig.baseBranch;
      } else if (key === 'schedule' && !val) {
        isMigrated = true;
        migratedConfig.schedule = [];
      } else if (key === 'schedule') {
        // massage to array first
        const schedules = is.string(val) ? [val] : val;
        // split 'and'
        for (let i = 0; i < schedules.length; i += 1) {
          if (
            schedules[i].includes(' and ') &&
            schedules[i].includes('before ') &&
            schedules[i].includes('after ')
          ) {
            const parsedSchedule = later.parse.text(
              // We need to massage short hours first before we can parse it
              schedules[i].replace(/( \d?\d)((a|p)m)/g, '$1:00$2')
            ).schedules[0];
            // Only migrate if the after time is greater than before, e.g. "after 10pm and before 5am"
            if (
              parsedSchedule &&
              parsedSchedule.t_a &&
              parsedSchedule.t_b &&
              parsedSchedule.t_a[0] > parsedSchedule.t_b[0]
            ) {
              isMigrated = true;
              const toSplit = schedules[i];
              schedules[i] = toSplit
                .replace(
                  /^(after|before) (.*?) and (after|before) (.*?)( |$)(.*)/,
                  '$1 $2 $6'
                )
                .trim();
              schedules.push(
                toSplit
                  .replace(
                    /^(after|before) (.*?) and (after|before) (.*?)( |$)(.*)/,
                    '$3 $4 $6'
                  )
                  .trim()
              );
            }
          }
        }
        for (let i = 0; i < schedules.length; i += 1) {
          if (schedules[i].includes('on the last day of the month')) {
            isMigrated = true;
            schedules[i] = schedules[i].replace(
              'on the last day of the month',
              'on the first day of the month'
            );
          }
          if (schedules[i].includes('on every weekday')) {
            isMigrated = true;
            schedules[i] = schedules[i].replace(
              'on every weekday',
              'every weekday'
            );
          }
          if (schedules[i].endsWith(' every day')) {
            isMigrated = true;
            schedules[i] = schedules[i].replace(' every day', '');
          }
          if (
            schedules[i].match(
              /every (mon|tues|wednes|thurs|fri|satur|sun)day$/
            )
          ) {
            isMigrated = true;
            schedules[i] = schedules[i].replace(/every ([a-z]*day)$/, 'on $1');
          }
          if (schedules[i].endsWith('days')) {
            isMigrated = true;
            schedules[i] = schedules[i].replace('days', 'day');
          }
        }
        if (isMigrated) {
          if (is.string(val) && schedules.length === 1) {
            [migratedConfig.schedule] = schedules;
          } else {
            migratedConfig.schedule = schedules;
          }
        }
      } else if (is.string(val) && val.startsWith('{{semanticPrefix}}')) {
        isMigrated = true;
        migratedConfig[key] = val.replace(
          '{{semanticPrefix}}',
          '{{#if semanticCommitType}}{{semanticCommitType}}{{#if semanticCommitScope}}({{semanticCommitScope}}){{/if}}: {{/if}}'
        );
      } else if (key === 'depTypes' && is.array(val)) {
        val.forEach(depType => {
          if (is.object(depType) && !is.array(depType)) {
            const depTypeName = depType.depType;
            if (depTypeName) {
              migratedConfig.packageRules = migratedConfig.packageRules || [];
              const newPackageRule = migrateConfig(depType).migratedConfig;
              delete newPackageRule.depType;
              newPackageRule.depTypeList = [depTypeName];
              migratedConfig.packageRules.push(newPackageRule);
            }
          }
        });
        isMigrated = true;
        delete migratedConfig.depTypes;
      } else if (optionTypes[key] === 'json' && is.boolean(val)) {
        isMigrated = true;
        migratedConfig[key] = { enabled: val };
      } else if (optionTypes[key] === 'boolean') {
        if (val === 'true') {
          migratedConfig[key] = true;
        } else if (val === 'false') {
          migratedConfig[key] = false;
        }
      } else if (
        optionTypes[key] === 'string' &&
        is.array(val) &&
        val.length === 1
      ) {
        migratedConfig[key] = `${val[0]}`;
      } else if (key === 'node' && val.enabled === true) {
        isMigrated = true;
        delete migratedConfig.node.enabled;
        migratedConfig.travis = migratedConfig.travis || {};
        migratedConfig.travis.enabled = true;
        if (!Object.keys(migratedConfig.node).length) {
          delete migratedConfig.node;
        } else {
          const subMigrate = migrateConfig(migratedConfig.node);
          migratedConfig.node = subMigrate.migratedConfig;
        }
      } else if (is.array(val)) {
        const newArray = [];
        for (const item of migratedConfig[key]) {
          if (is.object(item) && !is.array(item)) {
            const arrMigrate = migrateConfig(item);
            newArray.push(arrMigrate.migratedConfig);
            if (arrMigrate.isMigrated) {
              isMigrated = true;
            }
          } else {
            newArray.push(item);
          }
        }
        migratedConfig[key] = newArray;
      } else if (is.object(val)) {
        const subMigrate = migrateConfig(migratedConfig[key]);
        if (subMigrate.isMigrated) {
          isMigrated = true;
          migratedConfig[key] = subMigrate.migratedConfig;
        }
      } else if (
        (key === 'prBody' || key.startsWith('commitMessage')) &&
        (val.includes('currentVersion') || val.includes('newVersion'))
      ) {
        isMigrated = true;
        migratedConfig[key] = val
          .replace(/currentVersion/g, 'currentValue')
          .replace(/newVersion/g, 'newValue')
          .replace(/newValueMajor/g, 'newMajor')
          .replace(/newValueMinor/g, 'newMinor');
      }
    }
    return { isMigrated, migratedConfig };
  } catch (err) /* istanbul ignore next */ {
    logger.debug({ config }, 'migrateConfig() error');
    throw err;
  }
}
<|endoftext|>


<commit_before>/* SQB
 ------------------------
 (c) 2017-present Panates
 SQB may be freely distributed under the MIT license.
 For details and documentation:
 https://panates.github.io/sqb/
 */

const assert = require('assert');

const SchemaFields = ['schema_name', 'create_date'];
const TableFields = ['schema_name', 'table_name', 'table_comments', 'num_rows',
  'read_only'];
const ColumnFields = ['schema_name', 'table_name', 'column_name', 'data_type',
  'data_length', 'data_precision', 'data_scale', 'nullable',
  'column_comments'];
const PrimaryKeyFields = ['schema_name', 'table_name', 'constraint_name',
  'status', 'columns'];
const ForeignKeyFields = ['schema_name', 'table_name', 'constraint_name',
  'status', 'column_name', 'r_schema', 'r_table_name', 'r_columns'];

/**
 * @class
 * @public
 */
class DatabaseMetaData {

  /**
   *
   * @param {DbPool|Connection} dbobj
   */
  constructor(dbobj) {
    this.dbobj = dbobj;
  }

  select(...columns) {
    return new MetaDataSelect(this.dbobj, columns);
  }

}

class MetaDataSelect {

  constructor(dbobj, columns) {
    this.dbobj = dbobj;
    this.dbpool = dbobj.isConnection ? dbobj.dbpool : dbobj;
    this._columns = columns;
  }

  from(tableName) {
    tableName = String(tableName);
    assert(['schemas', 'tables', 'columns', 'primary_keys',
      'foreign_keys'].includes(tableName
        .toLowerCase()), 'Unknown table "' + tableName + '"');
    let subSelect;
    let sourceFields;
    const listFields = [];

    const plugin = this.dbpool.nastedPool;
    if (tableName === 'schemas') {
      assert(typeof plugin.metaDataSelectSchemas === 'function',
          'Connecting plugin does not support "metaDataSelectSchemas"');

      sourceFields = SchemaFields;
      subSelect = plugin.metaDataSelectSchemas(this.dbobj);

    } else if (tableName === 'tables') {
      assert(typeof plugin.metaDataSelectTables === 'function',
          'Connecting plugin does not support "metaDataSelectTables"');
      sourceFields = TableFields;
      subSelect = plugin.metaDataSelectTables(this.dbobj);

    } else if (tableName === 'columns') {
      assert(typeof plugin.metaDataSelectColumns === 'function',
          'Connecting plugin does not support "metaDataSelectColumns"');
      sourceFields = ColumnFields;
      subSelect = plugin.metaDataSelectColumns(this.dbobj);

    } else if (tableName === 'primary_keys') {
      assert(typeof plugin.metaDataSelectPrimaryKeys === 'function',
          'Connecting plugin does not support "metaDataSelectPrimaryKeys"');
      sourceFields = PrimaryKeyFields;
      subSelect = plugin.metaDataSelectPrimaryKeys(this.dbobj);

    } else if (tableName === 'foreign_keys') {
      assert(typeof plugin.metaDataSelectForeignKeys === 'function',
          'Connecting plugin does not support "metaDataSelectForeignKeys"');
      sourceFields = ForeignKeyFields;
      subSelect = plugin.metaDataSelectForeignKeys(this.dbobj);
    }

    for (let col of this._columns) {
      col = String(col).toLowerCase();
      if (sourceFields.includes(col) && !listFields.includes(col))
        listFields.push(col);
    }

    const query = this.dbobj
        .select(...listFields)
        .from(subSelect);
    if (subSelect._onfetchrow && subSelect._onfetchrow.length)
      for (const fn of subSelect._onfetchrow)
        query.onFetchRow(fn);
    return query;
  }

}

module.exports = DatabaseMetaData;
<commit_msg>Move to ES5.1<commit_after>/* SQB
 ------------------------
 (c) 2017-present Panates
 SQB may be freely distributed under the MIT license.
 For details and documentation:
 https://panates.github.io/sqb/
 */
/**
 * Module dependencies.
 * @private
 */
const assert = require('assert');

const SchemaFields = ['schema_name', 'create_date'];
const TableFields = ['schema_name', 'table_name', 'table_comments', 'num_rows',
  'read_only'];
const ColumnFields = ['schema_name', 'table_name', 'column_name', 'data_type',
  'data_length', 'data_precision', 'data_scale', 'nullable',
  'column_comments'];
const PrimaryKeyFields = ['schema_name', 'table_name', 'constraint_name',
  'status', 'columns'];
const ForeignKeyFields = ['schema_name', 'table_name', 'constraint_name',
  'status', 'column_name', 'r_schema', 'r_table_name', 'r_columns'];

/**
 * Expose `DatabaseMetaData`.
 */

module.exports = DatabaseMetaData;

/**
 * @param {DbPool|Connection} dbobj
 * @constructor
 */
function DatabaseMetaData(dbobj) {
  this.dbobj = dbobj;
}

const proto = DatabaseMetaData.prototype = {};
proto.constructor = DatabaseMetaData;

proto.select = function(column) {
  const o = Object.create(MetaDataSelect.prototype);
  MetaDataSelect.apply(o, arguments);
  return o;
};

/**
 *
 * @param {Object} dbobj
 * @param {...*} columns
 * @constructor
 */
function MetaDataSelect(dbobj, columns) {
  this.dbobj = dbobj;
  this.dbpool = dbobj.isConnection ? dbobj.dbpool : dbobj;
  this._columns = columns;
}

const proto2 = MetaDataSelect.prototype = {};
proto2.constructor = MetaDataSelect;

proto2.from = function(tableName) {
  tableName = String(tableName);
  assert(['schemas', 'tables', 'columns', 'primary_keys',
    'foreign_keys'].includes(tableName
      .toLowerCase()), 'Unknown table "' + tableName + '"');
  var subSelect;
  var sourceFields;
  const listFields = [];

  const plugin = this.dbpool.nastedPool;
  if (tableName === 'schemas') {
    assert(typeof plugin.metaDataSelectSchemas === 'function',
        'Connecting plugin does not support "metaDataSelectSchemas"');

    sourceFields = SchemaFields;
    subSelect = plugin.metaDataSelectSchemas(this.dbobj);

  } else if (tableName === 'tables') {
    assert(typeof plugin.metaDataSelectTables === 'function',
        'Connecting plugin does not support "metaDataSelectTables"');
    sourceFields = TableFields;
    subSelect = plugin.metaDataSelectTables(this.dbobj);

  } else if (tableName === 'columns') {
    assert(typeof plugin.metaDataSelectColumns === 'function',
        'Connecting plugin does not support "metaDataSelectColumns"');
    sourceFields = ColumnFields;
    subSelect = plugin.metaDataSelectColumns(this.dbobj);

  } else if (tableName === 'primary_keys') {
    assert(typeof plugin.metaDataSelectPrimaryKeys === 'function',
        'Connecting plugin does not support "metaDataSelectPrimaryKeys"');
    sourceFields = PrimaryKeyFields;
    subSelect = plugin.metaDataSelectPrimaryKeys(this.dbobj);

  } else if (tableName === 'foreign_keys') {
    assert(typeof plugin.metaDataSelectForeignKeys === 'function',
        'Connecting plugin does not support "metaDataSelectForeignKeys"');
    sourceFields = ForeignKeyFields;
    subSelect = plugin.metaDataSelectForeignKeys(this.dbobj);
  }

  this._columns.forEach(function(col) {
    col = String(col).toLowerCase();
    if (sourceFields.includes(col) && !listFields.includes(col))
      listFields.push(col);
  });

  const query = this.dbobj.select.apply(this.dbobj, listFields)
      .from(subSelect);
  if (subSelect._onfetchrow && subSelect._onfetchrow.length)
    subSelect._onfetchrow.forEach(function(fn) {
      query.onFetchRow(fn);
    });
  return query;
};

<|endoftext|>