<commit_before>var h = require('hyperscript')

/*
element classes are set with BEM convention.
https://css-tricks.com/bem-101/

B = block. module name, on the top level of the component.
E = element. a specific part of the component
M = modifier. something that changes an element (or block)
*/

var Menu = require('./menu')

module.exports = function (onSelect) {

  var names = []
  var tabs = h('div.row.hypertabs__tabs')
  var content = h('div.row.hypertabs__content')

  var d = h('div.hypertabs.column', Menu(content), h('div.column', content))

  d.add = function (tab, change) {
    tab.style.display = 'none'
    var index = content.children.length
    content.appendChild(tab)
    if(change !== false) d.select(index)
  }

  function find(name) {
    if(Number.isInteger(name)) return content.children[name]

    for(var i = 0; i < content.children.length; i++)
      if(content.children[i].id == name) return i

    return -1
  }

  d.has = function (name) {
    return ~find(name)
  }

  d.select = function (index) {
    if('string' === typeof index) index = find(index)

    var prev = d.selectedTab
    d.selected = selected = index
    ;[].forEach.call(content.children, function (tab, i) {
      tab.style.display = i == index ? 'flex' : 'none'
    })
    onSelect && onSelect(index)
  }

  d.selectRelative = function (n) {
    d.select(selected + n)
  }

  d.remove = function (i) {
    if(i < 0 || i > content.children.length) return
    content.removeChild(content.children[i])
    if(selected === i)
      d.select(i < content.children.length ? i : 0)
  }

  return d
}

<commit_msg>support change and split options on select<commit_after>var h = require('hyperscript')

/*
element classes are set with BEM convention.
https://css-tricks.com/bem-101/

B = block. module name, on the top level of the component.
E = element. a specific part of the component
M = modifier. something that changes an element (or block)
*/

var Menu = require('./menu')

module.exports = function (onSelect) {

  var names = []
  var tabs = h('div.row.hypertabs__tabs')
  var content = h('div.row.hypertabs__content')

  var d = h('div.hypertabs.column', Menu(content), h('div.column', content))

  d.add = function (tab, change, split) {
    console.log(tab, change, split)
    if(!split) tab.style.display = 'none'
    var index = content.children.length
    content.appendChild(tab)
    if(change !== false && !split) d.select(index)
  }

  function find(name) {
    if(Number.isInteger(name)) return content.children[name]

    for(var i = 0; i < content.children.length; i++)
      if(content.children[i].id == name) return i

    return -1
  }

  d.has = function (name) {
    return ~find(name)
  }

  d.select = function (index, change, split) {
    if('string' === typeof index) index = find(index)

    var max = content.children.length - 1
    if(index > max) index = 0
    if(index < 0) index = max

    if(!change) return

    var prev = d.selectedTab
    d.selected = selected = index

    if(split)
      content.children[index].style.display = 'flex'
    else
      ;[].forEach.call(content.children, function (tab, i) {
        tab.style.display = i == index ? 'flex' : 'none'
      })
    onSelect && onSelect(index)
  }

  d.selectRelative = function (n) {
    d.select(selected + n)
  }

  d.remove = function (i) {
    if(i < 0 || i > content.children.length) return
    content.removeChild(content.children[i])
    if(selected === i)
      d.select(i < content.children.length ? i : 0)
  }

  return d
}

<|endoftext|>


<commit_before>(function() {
  var Campfire, bot, campfire, campfireAccount, campfireToken, config, configYaml, http, roomId, targetHost, targetPath, targetPort, users;
  Campfire = require('../vendor/campfire').Campfire;
  http = require('http');
  config = {};
  if (require('path').existsSync('config.yml')) {
    configYaml = require('fs').readFileSync('config.yml', 'utf8');
    config = require('yaml').eval(configYaml);
  }
  campfireToken = process.env.CAMPFIRE_TOKEN || config.campfireToken;
  campfireAccount = process.env.CAMPFIRE_ACCOUNT || config.campfireAccount;
  roomId = process.env.CAMPFIRE_ROOM || config.campfireRoomId;
  targetHost = process.env.TARGET_HOST || config.targetHost;
  targetPath = process.env.TARGET_PATH || config.targetPath;
  targetPort = targetHost === 'localhost' ? 3000 : 80;
  campfire = new Campfire({
    ssl: true,
    token: campfireToken,
    account: campfireAccount
  });
  bot = {};
  users = {};
  campfire.me(function(response) {
    return bot = response.user;
  });
  campfire.room(roomId, function(room) {
    var postMessage;
    room.join(function() {
      console.log("Joining " + room.name);
      return room.listen(function(msg) {
        return postMessage(msg.body, msg.user_id);
      });
    });
    process.on('SIGINT', function() {
      return room.leave(function() {
        console.log("Exiting room");
        return process.exit();
      });
    });
    return postMessage = function(messageBody, userId) {
      var body, httpOptions, request;
      console.log("Posting '" + messageBody.length + "' chars for " + userId);
      body = JSON.stringify({
        status: {
          message: messageBody,
          developer_id: userId
        }
      });
      httpOptions = {
        host: targetHost,
        port: targetPort,
        method: 'POST',
        path: targetPath,
        headers: {
          'Content-Type': 'application/json',
          'Content-Length': body.length
        }
      };
      request = http.request(httpOptions);
      request.write(body);
      return request.end();
    };
  });
}).call(this);
<commit_msg>Compiled coffeescript<commit_after>(function() {
  var Campfire, bot, campfire, campfireAccount, campfireToken, config, configYaml, http, roomId, targetHost, targetPath, targetPort, users;
  Campfire = require('../vendor/campfire').Campfire;
  http = require('http');
  config = {};
  if (require('path').existsSync('config.yml')) {
    configYaml = require('fs').readFileSync('config.yml', 'utf8');
    config = require('yaml').eval(configYaml);
  }
  campfireToken = process.env.CAMPFIRE_TOKEN || config.campfireToken;
  campfireAccount = process.env.CAMPFIRE_ACCOUNT || config.campfireAccount;
  roomId = process.env.CAMPFIRE_ROOM || config.campfireRoomId;
  targetHost = process.env.TARGET_HOST || config.targetHost;
  targetPath = process.env.TARGET_PATH || config.targetPath;
  targetPort = targetHost === 'localhost' ? 3000 : 80;
  campfire = new Campfire({
    ssl: true,
    token: campfireToken,
    account: campfireAccount
  });
  bot = {};
  users = {};
  campfire.me(function(response) {
    return bot = response.user;
  });
  campfire.room(roomId, function(room) {
    var postMessage;
    room.join(function() {
      console.log("Joining " + room.name);
      return room.listen(function(msg) {
        if (msg.type === 'TextMessage' && msg.user_id !== bot.id) {
          return postMessage(msg.body, msg.user_id);
        }
      });
    });
    process.on('SIGINT', function() {
      return room.leave(function() {
        console.log("Exiting room");
        return process.exit();
      });
    });
    return postMessage = function(messageBody, userId) {
      var body, httpOptions, request;
      console.log("Posting '" + messageBody.length + "' chars for " + userId);
      body = JSON.stringify({
        status: {
          message: messageBody,
          developer_id: userId
        }
      });
      httpOptions = {
        host: targetHost,
        port: targetPort,
        method: 'POST',
        path: targetPath,
        headers: {
          'Content-Type': 'application/json',
          'Content-Length': body.length
        }
      };
      request = http.request(httpOptions);
      request.write(body);
      return request.end();
    };
  });
}).call(this);
<|endoftext|>


<commit_before>var events = require('events');
var fs = require('fs');
var os = require('os');
var path = require('path'),
  basename = path.basename;
var util = require('util');
var Writable = require('stream').Writable;
var merge = require('cli-util').merge;

var pkg = require(path.join(__dirname, 'package.json'));
var major = parseInt(pkg.version.split('.')[0]);
var z;

var RAW = 'raw';
var STREAM = 'stream';
var FILE = 'file';

var LEVELS = {
  trace: 10,
  debug: 20,
  info: 30,
  warn: 40,
  error: 50,
  fatal: 60,
  none: 70
}

var BITWISE = {
  none: 0,
  trace: 1,
  debug: 2,
  info: 4,
  warn: 8,
  error: 16,
  fatal: 32,
  all: 63
}

var keys = Object.keys(LEVELS);
keys.pop();

var defaults = {
  name: basename(process.argv[1]),
  json: false,
  src: false,
  console: false
}

/**
 *  Create a Logger instance.
 *
 *  @param conf The logger configuration.
 *  @param bitwise A boolean indicating that log levels
 *  should use bitwise operators.
 */
var Logger = function(conf, bitwise) {
  conf = conf || {};
  conf.bitwise = (bitwise === true);
  this.configure(bitwise);
  function filter(t, k, v) {
    if(k !== 'streams') {
      t[k] = v;
    }
  }
  this.conf = merge(conf, merge(defaults, {}), filter);
  this.conf.streams = conf.streams || {
    stream: process.stdout
  }
  this.pid = this.conf.pid || process.pid;
  this.hostname = this.conf.hostname || os.hostname();
  if(this.conf.console) {
    this.writers = {};
    this.writers[LEVELS.trace] = console.log;
    this.writers[LEVELS.debug] = console.log;
    this.writers[LEVELS.info] = console.info;
    this.writers[LEVELS.warn] = console.warn;
    this.writers[LEVELS.error] = console.error;
    this.writers[LEVELS.fatal] = console.error;
  }
  this.streams = this.initialize();
}

util.inherits(Logger, events.EventEmitter);

/**
 *  Configure bitwise log levels.
 *
 *  @api private
 *
 *  @param bitwise A boolean indicating that log levels
 *  should use bitwise operators.
 */
Logger.prototype.configure = function(bitwise) {
  this._levels = {}
  var target = bitwise ? BITWISE : LEVELS;
  for(var z in target) {
    this._levels[z] = target[z];
    this[z.toUpperCase()] = this._levels[z];
  }
}

/**
 *  Resolve a level string name to the corresponding
 *  integer value.
 *
 *  @api private
 *
 *  @param level A string or integer.
 *
 *  @return The level integer or undefined if a string value
 *  does not correspond to a known log level.
 */
Logger.prototype.resolve = function(level) {
  var msg = 'Unknown log level \'' + level + '\'';
  var key, value, z, exists = false;
  if(typeof(level) == 'string') {
    key = level.toLowerCase();
    level = this._levels[key];
  }
  for(z in this._levels) {
    if(this._levels[z] === level) {
      exists = true;
      break;
    }
  }
  if(level === undefined || !exists) throw new Error(msg);
  return level;
}

/**
 *  Initialize the output streams.
 *
 *  @api private
 */
Logger.prototype.initialize = function() {
  var streams = [], scope = this;
  var source = this.conf.streams;
  function append(stream, level, name) {
    var lvl = level || scope.conf.level || scope._levels.info;
    streams.push({stream: stream,
      level: scope.resolve(lvl), name: name})
    stream.on('error', function(e) {
      scope.emit('error', e, stream);
    })
  }
  function wrap(source) {
    var stream = source.stream;
    if(source.path) {
      var opts = {
        flags: source.flags || 'a',
        mode: source.mode,
        encoding: source.encoding
      }
      try {
        source.stream = fs.createWriteStream(source.path, opts);
      }catch(e) {
        scope.emit('error', e);
      }
    }
    if(source.stream && !(source.stream instanceof Writable)
      && source.stream !== process.stdout
      && source.stream !== process.stderr) {
      throw new Error('Invalid stream specified');
    }
    append(source.stream, source.level, source.name);
  }
  if(source && typeof(source) == 'object' && !Array.isArray(source)) {
    //console.dir(source);
    wrap(source);
  }else if(Array.isArray(source)) {
    source.forEach(function(source) {
      wrap(source);
    })
  }else{
    throw new Error('Invalid streams configuration');
  }
  return streams;
}

/**
 *  Retrieve caller info, used when the src configuration
 *  property is true to determine the file and line number
 *  that the log call came from.
 *
 *  @api private
 *
 *  @see http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
 */
Logger.prototype.getCallerInfo = function() {
  var obj = {};
  var limit = Error.stackTraceLimit;
  var prepare = Error.prepareStackTrace;
  Error.captureStackTrace(this, arguments.callee);
  Error.prepareStackTrace = function (_, stack) {
    var caller = stack[3];
    obj.file = caller.getFileName();
    obj.line = caller.getLineNumber();
    var func = caller.getFunctionName();
    if(func) obj.func = func;
    obj.stack = stack.slice(3);
    obj.stack.forEach(function(caller, index, arr) {
      arr[index] = '' + caller;
    })
    return stack;
  };
  var stack = this.stack;
  Error.prepareStackTrace = prepare;
  return obj;
}

/**
 *  Retrieve a log record.
 *
 *  @api private
 *
 *  @param level The log level.
 *  @param message The log message.
 *  @param ... The message replacement parameters.
 */
Logger.prototype.getLogRecord = function(level, message) {
  var parameters = [].slice.call(arguments, 2), args, z;
  //var raw = parameters.slice(0);
  var err = (message instanceof Error) ? message : null;
  var obj = (!err && message && typeof(message) == 'object') ? message : null;
  if(parameters.length && !this.conf.console) {
    if(!err && !obj) {
      parameters.unshift(message);
    }
    message = util.format.apply(util, parameters);
  }
  if(err) {
    if(arguments.length == 2) {
      message = err.message;
    }
  }
  var record = message;
  if(this.conf.console) {
    record = {message: message, parameters: parameters};
  }else if(this.conf.json) {
    record = {};
    record.time = new Date().toISOString();
    if(obj) {
      for(z in obj) {
        record[z] = obj[z];
      }
      if(arguments.length == 2) {
        message = '';
      }
    }
    record.pid = this.pid;
    record.hostname = this.hostname;
    record.name = this.conf.name;
    record.msg = message;
    record.level = level;
    if(err) {
      record.err = {
        message: err.message,
        name: err.name,
        stack: err.stack
      }
    }
    if(this.conf.src) {
      record.src = this.getCallerInfo();
    }
    record.v = major;
  }
  return record;
}

/**
 *  Write the log record to stream(s) or dispatch
 *  the write event if there are listeners for the write
 *  event.
 *
 *  @api private
 *
 *  @param level The log level.
 *  @param record The log record.
 */
Logger.prototype.write = function(level, record) {
  var i, target, listeners = this.listeners('write');
  for(i = 0;i < this.streams.length;i++) {
    target = this.streams[i];
    if(!listeners.length && this.conf.json && target.type !== RAW) {
      record = JSON.stringify(record);
    }
    if(level >= target.level) {
      if(listeners.length) {
        this.emit('write', record, target.stream);
      }else{
        if(this.conf.console && this.writers[level]) {
          this.writers[level].apply(
            console, [record.message].concat(record.parameters));
        }else{
          target.stream.write(record + '\n');
        }
      }
    }
  }
}

/**
 *  Log a message.
 *
 *  @api private
 *
 *  @param level The log level.
 *  @param message The log message.
 *  @param ... The message replacement parameters.
 */
Logger.prototype.log = function(level, message) {
  if(!level) return false;
  if(level && !message) return this.enabled(level);
  this.write(level, this.getLogRecord.apply(this, arguments));
}

/**
 *  Determine if a log level is enabled.
 *
 *  @api private
 *
 *  @param level The target log level.
 */
Logger.prototype.enabled = function(level) {
  var stream;
  for(var i = 0;i < this.streams.length;i++) {
    stream = this.streams[i];
    if(level >= stream.level) {
      return true;
    }
  }
  return false;
}

/**
 *  Get or set the current log level.
 *
 *  @param level A log level to set on all streams.
 *
 *  @return The lowest log level when no arguments are specified.
 */
Logger.prototype.level = function(level) {
  var i, stream, min;
  if(!arguments.length) {
    min = this._levels.none;
    for(i = 0;i < this.streams.length;i++) {
      stream = this.streams[i];
      min = Math.min(min, stream.level);
    }
    return min;
  }else{
    level = this.resolve(level);
    for(i = 0;i < this.streams.length;i++) {
      stream = this.streams[i];
      stream.level = level;
    }
  }
}

/**
 *  Log a trace message.
 *
 *  @param message The log message.
 *  @param ... The message replacement parameters.
 */
Logger.prototype.trace = function() {
  if(!arguments.length) return this.enabled(this._levels.trace);
  var args = [].slice.call(arguments, 0);
  args.unshift(this._levels.trace);
  this.log.apply(this, args);
}

/**
 *  Log a debug message.
 *
 *  @param message The log message.
 *  @param ... The message replacement parameters.
 */
Logger.prototype.debug = function() {
  if(!arguments.length) return this.enabled(this._levels.debug);
  var args = [].slice.call(arguments, 0);
  args.unshift(this._levels.debug);
  this.log.apply(this, args);
}

/**
 *  Log an info message.
 *
 *  @param message The log message.
 *  @param ... The message replacement parameters.
 */
Logger.prototype.info = function() {
  if(!arguments.length) return this.enabled(this._levels.info);
  var args = [].slice.call(arguments, 0);
  args.unshift(this._levels.info);
  this.log.apply(this, args);
}

/**
 *  Log a warn message.
 *
 *  @param message The log message.
 *  @param ... The message replacement parameters.
 */
Logger.prototype.warn = function() {
  if(!arguments.length) return this.enabled(this._levels.warn);
  var args = [].slice.call(arguments, 0);
  args.unshift(this._levels.warn);
  this.log.apply(this, args);
}

/**
 *  Log an error message.
 *
 *  @param message The log message.
 *  @param ... The message replacement parameters.
 */
Logger.prototype.error = function() {
  if(!arguments.length) return this.enabled(this._levels.error);
  var args = [].slice.call(arguments, 0);
  args.unshift(this._levels.error);
  this.log.apply(this, args);
}

/**
 *  Log a fatal message.
 *
 *  @param message The log message.
 *  @param ... The message replacement parameters.
 */
Logger.prototype.fatal = function() {
  if(!arguments.length) return this.enabled(this._levels.fatal);
  var args = [].slice.call(arguments, 0);
  args.unshift(this._levels.fatal);
  this.log.apply(this, args);
}

/**
 *  Create a logger.
 *
 *  @param conf The logger configuration.
 *  @param bitwise A boolean indicating that log levels
 *  should use bitwise operators.
 */
module.exports = function(conf, bitwise) {
  var logger = new Logger(conf, bitwise);
  return logger;
}

module.exports.levels = LEVELS;
module.exports.bitwise = BITWISE;
module.exports.keys = keys;
module.exports.Logger = Logger;
for(z in LEVELS) {
  module.exports[z.toUpperCase()] = LEVELS[z];
}
for(z in BITWISE) {
  module.exports['BW_' + z.toUpperCase()] = BITWISE[z];
}
module.exports.LOG_VERSION = major;
<commit_msg>Tidy inner functions.<commit_after>var events = require('events');
var fs = require('fs');
var os = require('os');
var path = require('path'),
  basename = path.basename;
var util = require('util');
var Writable = require('stream').Writable;
var merge = require('cli-util').merge;

var pkg = require(path.join(__dirname, 'package.json'));
var major = parseInt(pkg.version.split('.')[0]);
var z;

var RAW = 'raw';
var STREAM = 'stream';
var FILE = 'file';

var LEVELS = {
  trace: 10,
  debug: 20,
  info: 30,
  warn: 40,
  error: 50,
  fatal: 60,
  none: 70
}

var BITWISE = {
  none: 0,
  trace: 1,
  debug: 2,
  info: 4,
  warn: 8,
  error: 16,
  fatal: 32,
  all: 63
}

var keys = Object.keys(LEVELS);
keys.pop();

var defaults = {
  name: basename(process.argv[1]),
  json: false,
  src: false,
  console: false
}

/**
 *  Create a Logger instance.
 *
 *  @param conf The logger configuration.
 *  @param bitwise A boolean indicating that log levels
 *  should use bitwise operators.
 */
var Logger = function(conf, bitwise) {
  conf = conf || {};
  conf.bitwise = (bitwise === true);
  this.configure(bitwise);
  function filter(t, k, v) {
    if(k !== 'streams') {
      t[k] = v;
    }
  }
  this.conf = merge(conf, merge(defaults, {}), filter);
  this.conf.streams = conf.streams || {
    stream: process.stdout
  }
  this.pid = this.conf.pid || process.pid;
  this.hostname = this.conf.hostname || os.hostname();
  if(this.conf.console) {
    this.writers = {};
    this.writers[LEVELS.trace] = console.log;
    this.writers[LEVELS.debug] = console.log;
    this.writers[LEVELS.info] = console.info;
    this.writers[LEVELS.warn] = console.warn;
    this.writers[LEVELS.error] = console.error;
    this.writers[LEVELS.fatal] = console.error;
  }
  this.initialize();
}

util.inherits(Logger, events.EventEmitter);

/**
 *  Configure bitwise log levels.
 *
 *  @api private
 *
 *  @param bitwise A boolean indicating that log levels
 *  should use bitwise operators.
 */
Logger.prototype.configure = function(bitwise) {
  this._levels = {}
  var target = bitwise ? BITWISE : LEVELS;
  for(var z in target) {
    this._levels[z] = target[z];
    this[z.toUpperCase()] = this._levels[z];
  }
}

/**
 *  Resolve a level string name to the corresponding
 *  integer value.
 *
 *  @api private
 *
 *  @param level A string or integer.
 *
 *  @return The level integer or undefined if a string value
 *  does not correspond to a known log level.
 */
Logger.prototype.resolve = function(level) {
  var msg = 'Unknown log level \'' + level + '\'';
  var key, value, z, exists = false;
  if(typeof(level) == 'string') {
    key = level.toLowerCase();
    level = this._levels[key];
  }
  for(z in this._levels) {
    if(this._levels[z] === level) {
      exists = true;
      break;
    }
  }
  if(level === undefined || !exists) throw new Error(msg);
  return level;
}

/**
 *  Initialize the output streams.
 *
 *  @api private
 */
Logger.prototype.initialize = function() {
  this.streams = [];
  var source = this.conf.streams, i;
  if(source && typeof(source) == 'object' && !Array.isArray(source)) {
    this.convert(source);
  }else if(Array.isArray(source)) {
    for(i = 0;i < source.length;i++) {
      this.convert(source[i]);
    }
  }else{
    throw new Error('Invalid streams configuration');
  }
}

/**
 *  Append a stream.
 *
 *  @api private
 */
Logger.prototype.append = function(stream, level, name) {
  var scope = this;
  var lvl = level || this.conf.level || this._levels.info;
  this.streams.push({
    stream: stream,
    level: scope.resolve(lvl),
    name: name});
  stream.on('error', function(e) {
    scope.emit('error', e, stream);
  })
}

/**
 *  Convert a stream configuration object into a
 *  stream instance.
 *
 *  @api private
 *
 *  @param source The configuration stream object.
 */
Logger.prototype.convert = function(source) {
  var stream = source.stream, opts;
  if(source.path) {
    opts = {
      flags: source.flags || 'a',
      mode: source.mode,
      encoding: source.encoding
    }
    try {
      source.stream = fs.createWriteStream(source.path, opts);
    }catch(e) {
      this.emit('error', e);
    }
  }
  if(source.stream && !(source.stream instanceof Writable)
    && source.stream !== process.stdout
    && source.stream !== process.stderr) {
    throw new Error('Invalid stream specified');
  }
  this.append(source.stream, source.level, source.name);
}

/**
 *  Retrieve caller info, used when the src configuration
 *  property is true to determine the file and line number
 *  that the log call came from.
 *
 *  @api private
 *
 *  @see http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
 */
Logger.prototype.getCallerInfo = function() {
  var obj = {};
  var limit = Error.stackTraceLimit;
  var prepare = Error.prepareStackTrace;
  Error.captureStackTrace(this, arguments.callee);
  Error.prepareStackTrace = function (_, stack) {
    var caller = stack[3];
    obj.file = caller.getFileName();
    obj.line = caller.getLineNumber();
    var func = caller.getFunctionName();
    if(func) obj.func = func;
    obj.stack = stack.slice(3);
    obj.stack.forEach(function(caller, index, arr) {
      arr[index] = '' + caller;
    })
    return stack;
  };
  var stack = this.stack;
  Error.prepareStackTrace = prepare;
  return obj;
}

/**
 *  Retrieve a log record.
 *
 *  @api private
 *
 *  @param level The log level.
 *  @param message The log message.
 *  @param ... The message replacement parameters.
 */
Logger.prototype.getLogRecord = function(level, message) {
  var parameters = [].slice.call(arguments, 2), args, z;
  //var raw = parameters.slice(0);
  var err = (message instanceof Error) ? message : null;
  var obj = (!err && message && typeof(message) == 'object') ? message : null;
  if(parameters.length && !this.conf.console) {
    if(!err && !obj) {
      parameters.unshift(message);
    }
    message = util.format.apply(util, parameters);
  }
  if(err) {
    if(arguments.length == 2) {
      message = err.message;
    }
  }
  var record = message;
  if(this.conf.console) {
    record = {message: message, parameters: parameters};
  }else if(this.conf.json) {
    record = {};
    record.time = new Date().toISOString();
    if(obj) {
      for(z in obj) {
        record[z] = obj[z];
      }
      if(arguments.length == 2) {
        message = '';
      }
    }
    record.pid = this.pid;
    record.hostname = this.hostname;
    record.name = this.conf.name;
    record.msg = message;
    record.level = level;
    if(err) {
      record.err = {
        message: err.message,
        name: err.name,
        stack: err.stack
      }
    }
    if(this.conf.src) {
      record.src = this.getCallerInfo();
    }
    record.v = major;
  }
  return record;
}

/**
 *  Write the log record to stream(s) or dispatch
 *  the write event if there are listeners for the write
 *  event.
 *
 *  @api private
 *
 *  @param level The log level.
 *  @param record The log record.
 */
Logger.prototype.write = function(level, record) {
  var i, target, listeners = this.listeners('write');
  for(i = 0;i < this.streams.length;i++) {
    target = this.streams[i];
    if(!listeners.length && this.conf.json && target.type !== RAW) {
      record = JSON.stringify(record);
    }
    if(level >= target.level) {
      if(listeners.length) {
        this.emit('write', record, target.stream);
      }else{
        if(this.conf.console && this.writers[level]) {
          this.writers[level].apply(
            console, [record.message].concat(record.parameters));
        }else{
          target.stream.write(record + '\n');
        }
      }
    }
  }
  return (listeners.length === 0);
}

/**
 *  Log a message.
 *
 *  @api private
 *
 *  @param level The log level.
 *  @param message The log message.
 *  @param ... The message replacement parameters.
 */
Logger.prototype.log = function(level, message) {
  if(!level) return false;
  if(level && !message) return this.enabled(level);
  return this.write(level, this.getLogRecord.apply(this, arguments));
}

/**
 *  Determine if a log level is enabled.
 *
 *  @api private
 *
 *  @param level The target log level.
 */
Logger.prototype.enabled = function(level) {
  var stream;
  for(var i = 0;i < this.streams.length;i++) {
    stream = this.streams[i];
    if(level >= stream.level) {
      return true;
    }
  }
  return false;
}

/**
 *  Get or set the current log level.
 *
 *  @param level A log level to set on all streams.
 *
 *  @return The lowest log level when no arguments are specified.
 */
Logger.prototype.level = function(level) {
  var i, stream, min;
  if(!arguments.length) {
    min = this._levels.none;
    for(i = 0;i < this.streams.length;i++) {
      stream = this.streams[i];
      min = Math.min(min, stream.level);
    }
    return min;
  }else{
    level = this.resolve(level);
    for(i = 0;i < this.streams.length;i++) {
      stream = this.streams[i];
      stream.level = level;
    }
  }
}

/**
 *  Log a trace message.
 *
 *  @param message The log message.
 *  @param ... The message replacement parameters.
 */
Logger.prototype.trace = function() {
  var lvl = this._levels.trace;
  if(!arguments.length) return this.enabled(lvl);
  var args = [].slice.call(arguments, 0);
  args.unshift(lvl);
  return this.log.apply(this, args);
}

/**
 *  Log a debug message.
 *
 *  @param message The log message.
 *  @param ... The message replacement parameters.
 */
Logger.prototype.debug = function() {
  var lvl = this._levels.debug;
  if(!arguments.length) return this.enabled(lvl);
  var args = [].slice.call(arguments, 0);
  args.unshift(lvl);
  return this.log.apply(this, args);
}

/**
 *  Log an info message.
 *
 *  @param message The log message.
 *  @param ... The message replacement parameters.
 */
Logger.prototype.info = function() {
  var lvl = this._levels.info;
  if(!arguments.length) return this.enabled(lvl);
  var args = [].slice.call(arguments, 0);
  args.unshift(lvl);
  return this.log.apply(this, args);
}

/**
 *  Log a warn message.
 *
 *  @param message The log message.
 *  @param ... The message replacement parameters.
 */
Logger.prototype.warn = function() {
  var lvl = this._levels.warn;
  if(!arguments.length) return this.enabled(lvl);
  var args = [].slice.call(arguments, 0);
  args.unshift(lvl);
  return this.log.apply(this, args);
}

/**
 *  Log an error message.
 *
 *  @param message The log message.
 *  @param ... The message replacement parameters.
 */
Logger.prototype.error = function() {
  var lvl = this._levels.error;
  if(!arguments.length) return this.enabled(lvl);
  var args = [].slice.call(arguments, 0);
  args.unshift(lvl);
  return this.log.apply(this, args);
}

/**
 *  Log a fatal message.
 *
 *  @param message The log message.
 *  @param ... The message replacement parameters.
 */
Logger.prototype.fatal = function() {
  var lvl = this._levels.fatal;
  if(!arguments.length) return this.enabled(lvl);
  var args = [].slice.call(arguments, 0);
  args.unshift(lvl);
  return this.log.apply(this, args);
}

/**
 *  Create a logger.
 *
 *  @param conf The logger configuration.
 *  @param bitwise A boolean indicating that log levels
 *  should use bitwise operators.
 */
module.exports = function(conf, bitwise) {
  var logger = new Logger(conf, bitwise);
  return logger;
}

module.exports.levels = LEVELS;
module.exports.bitwise = BITWISE;
module.exports.keys = keys;
module.exports.Logger = Logger;
for(z in LEVELS) {
  module.exports[z.toUpperCase()] = LEVELS[z];
}
for(z in BITWISE) {
  module.exports['BW_' + z.toUpperCase()] = BITWISE[z];
}
module.exports.LOG_VERSION = major;
<|endoftext|>


<commit_before>'use strict';

var remote = require('remote');
var fs = require('fs');
var marked = require('marked');
fs.readFile('./README.md', 'utf-8', function(err,text){
//  document.write(marked(text));
});

function test(){
  alert("Hi!");
}
<commit_msg>20151126<commit_after>'use strict';

var remote = require('remote');
var fs = require('fs');
var marked = require('marked');
var x = document.querySelector(".editor");
var y = document.querySelector(".preview");
var z = document.querySelector("textarea");
fs.readFile('./README.md', 'utf-8', function(err,text){
//  document.write(marked(text));
  z.value = text;
  y.innerHTML = marked(text);
});
x.addEventListener('click',function(){
  console.log('x');
  x.style.display="none";
  y.style.display="block";
});
y.addEventListener('click',function(){
  console.log('x');
  y.style.display="none";
  x.style.display="block";
});
<|endoftext|>


<commit_before>require('source-map-support').install();
const path = require('path');
const { readdirSync } = require('fs');
const gitRev = require('git-rev-sync');
const compression = require('compression');
const serveStatic = require('serve-static');
const express = require('express');
const Bugsnag = require('bugsnag');
const Redis = require('ioredis');
const md5 = require('md5-hex');
const uwave = require('u-wave-core');
const createHttpApi = require('u-wave-http-api');
const createWebClient = require('@wlk/client/middleware').default;
const emojione = require('u-wave-web-emojione');
const waitlistRoulette = require('@wlk/u-wave-random-playlists');
const announce = require('u-wave-announce');
const ytSource = require('u-wave-source-youtube');
const scSource = require('u-wave-source-soundcloud');

const configPath = process.argv[2] || './config';
const config = require(path.resolve(process.cwd(), configPath));

Bugsnag.register(config.bugsnag, {
  appVersion: gitRev.short(__dirname),
});

const uw = uwave({
  redis: new Redis(config.redisPort),
  mongo: config.mongo,
});

uw.use(announce({
  url: 'https://wlk.yt/',
  socketUrl: 'wss://wlk.yt/',
  apiUrl: 'https://wlk.yt/v1',
  name: 'WLK',
  subtitle: 'International K-Pop community.',
  description: `
    WLK is a community dedicated to sharing the best South Korean music.
    Listen to what other people play live from YouTube and SoundCloud,
    share your opinion by talking to others and contribute to each day's
    unique playlist by hand-picking tracks yourself.

    ## Rules

    1. Play only Korean related songs.
    2. Songs that are over 7:00 minutes long might be skipped.
    3. Songs that are heavily downvoted might be skipped.
    4. Songs that are in the history (previous 25 songs) will be skipped.
    5. Try to play the best quality versions of songs.
    6. Chat in English!
    7. Don't spam the chat.
  `,
  seed: config.announceSeed,
}));

uw.use(waitlistRoulette());

uw.source(ytSource, {
  key: config.youtube.key,
  search: {
    videoSyndicated: 'any',
  },
});

uw.source(scSource, {
  key: config.soundcloud.key,
});

const app = express();
const server = app.listen(config.port);

app.use(Bugsnag.requestHandler);
app.use(compression());

app.use(serveStatic('./public'));

app.use('/v1', createHttpApi(uw, {
  secret: config.secret,
  mailTransport: config.mailTransport,
  createPasswordResetEmail: config.createPasswordResetEmail,
  // The web API needs an HTTP server to attach the WebSocket server to.
  server,
  recaptcha: config.recaptcha,
  onError(req, error) {
    Bugsnag.notify(error, {
      severity: error.status && error.status >= 500 && error.status < 600
        ? 'error'
        : 'warning',
      user: req.user ? {
        id: req.user.id,
        name: req.user.username,
      } : {
        // Pseudonymise so we can still track if it's a single user having
        // this issue or many.
        id: md5(req.ip).slice(0, 7),
      },
      context: `api: ${req.url}`,
    });
  },
}));

app.use('/assets/emoji/', serveStatic(config.customEmoji));
app.use('/assets/emoji/', emojione.middleware());

const customEmoji = readdirSync(config.customEmoji).reduce((o, name) => {
  o[name.replace(/\.[a-z]+$/, '')] = name;
  return o;
}, {});

app.use(createWebClient(uw, {
  apiUrl: '/v1',
  title: config.title,
  emoji: Object.assign(
    {},
    emojione.emoji,
    customEmoji,
  ),
  recaptcha: config.recaptcha && { key: config.recaptcha.key },
}));

app.use(Bugsnag.errorHandler);
<commit_msg>Alias /api to /v1.<commit_after>require('source-map-support').install();
const path = require('path');
const { readdirSync } = require('fs');
const gitRev = require('git-rev-sync');
const compression = require('compression');
const serveStatic = require('serve-static');
const express = require('express');
const Bugsnag = require('bugsnag');
const Redis = require('ioredis');
const md5 = require('md5-hex');
const uwave = require('u-wave-core');
const createHttpApi = require('u-wave-http-api');
const createWebClient = require('@wlk/client/middleware').default;
const emojione = require('u-wave-web-emojione');
const waitlistRoulette = require('@wlk/u-wave-random-playlists');
const announce = require('u-wave-announce');
const ytSource = require('u-wave-source-youtube');
const scSource = require('u-wave-source-soundcloud');

const configPath = process.argv[2] || './config';
const config = require(path.resolve(process.cwd(), configPath));

Bugsnag.register(config.bugsnag, {
  appVersion: gitRev.short(__dirname),
});

const uw = uwave({
  redis: new Redis(config.redisPort),
  mongo: config.mongo,
});

uw.use(announce({
  url: 'https://wlk.yt/',
  socketUrl: 'wss://wlk.yt/',
  apiUrl: 'https://wlk.yt/v1',
  name: 'WLK',
  subtitle: 'International K-Pop community.',
  description: `
    WLK is a community dedicated to sharing the best South Korean music.
    Listen to what other people play live from YouTube and SoundCloud,
    share your opinion by talking to others and contribute to each day's
    unique playlist by hand-picking tracks yourself.

    ## Rules

    1. Play only Korean related songs.
    2. Songs that are over 7:00 minutes long might be skipped.
    3. Songs that are heavily downvoted might be skipped.
    4. Songs that are in the history (previous 25 songs) will be skipped.
    5. Try to play the best quality versions of songs.
    6. Chat in English!
    7. Don't spam the chat.
  `,
  seed: config.announceSeed,
}));

uw.use(waitlistRoulette());

uw.source(ytSource, {
  key: config.youtube.key,
  search: {
    videoSyndicated: 'any',
  },
});

uw.source(scSource, {
  key: config.soundcloud.key,
});

const app = express();
const server = app.listen(config.port);

app.use(Bugsnag.requestHandler);
app.use(compression());

app.use(serveStatic('./public'));

const httpApi = createHttpApi(uw, {
  secret: config.secret,
  mailTransport: config.mailTransport,
  createPasswordResetEmail: config.createPasswordResetEmail,
  // The web API needs an HTTP server to attach the WebSocket server to.
  server,
  recaptcha: config.recaptcha,
  onError(req, error) {
    Bugsnag.notify(error, {
      severity: error.status && error.status >= 500 && error.status < 600
        ? 'error'
        : 'warning',
      user: req.user ? {
        id: req.user.id,
        name: req.user.username,
      } : {
        // Pseudonymise so we can still track if it's a single user having
        // this issue or many.
        id: md5(req.ip).slice(0, 7),
      },
      context: `api: ${req.url}`,
    });
  },
});
app.use('/v1', httpApi);
// https://github.com/u-wave/web/issues/1068
app.use('/api', httpApi);

app.use('/assets/emoji/', serveStatic(config.customEmoji));
app.use('/assets/emoji/', emojione.middleware());

const customEmoji = readdirSync(config.customEmoji).reduce((o, name) => {
  o[name.replace(/\.[a-z]+$/, '')] = name;
  return o;
}, {});

app.use(createWebClient(uw, {
  apiUrl: '/v1',
  title: config.title,
  emoji: Object.assign(
    {},
    emojione.emoji,
    customEmoji,
  ),
  recaptcha: config.recaptcha && { key: config.recaptcha.key },
}));

app.use(Bugsnag.errorHandler);
<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');
const {Readable} = require('stream');
const sysPath = require('path');
const {promisify} = require('util');
const picomatch = require('picomatch');
const readdir = promisify(fs.readdir);
const stat = promisify(fs.stat);
const lstat = promisify(fs.lstat);

/**
 * @typedef {Object} EntryInfo
 * @property {String} path
 * @property {String} fullPath
 * @property {fs.Stats} stats
 * @property {String} basename
 */

const BANG = '!';
const normalizeFilter = (filter) => {
  if (filter === undefined) return;
  if (typeof filter === "function") return filter;

  if (typeof filter === "string") {
    const glob = picomatch(filter.trim());
    return (entry) => glob(entry.basename);
  }

  if (Array.isArray(filter)) {
    const positive = [];
    const negative = [];
    for (const item of filter) {
      const trimmed = item.trim();
      if (trimmed.charAt(0) === BANG) {
        negative.push(picomatch(trimmed.slice(1)));
      } else {
        positive.push(picomatch(trimmed));
      }
    }

    if (negative.length > 0) {
      if (positive.length > 0) {
        return (entry) => positive.some(f => f(entry.basename)) &&
          !negative.every(f => f(entry.basename));
      } else {
        return (entry) => !negative.every(f => f(entry.basename));
      }
    } else {
      return (entry) => positive.some(f => f(entry.basename));
    }
  }
};

const ENOENT = 'ENOENT';
const FILE_TYPE = 'files';
const DIR_TYPE = 'directories';
const FILE_DIR_TYPE = 'files_directories';
const ALL_TYPE = 'all';
const TYPES = [FILE_TYPE, DIR_TYPE, FILE_DIR_TYPE, ALL_TYPE];
const FILE_TYPES = Object.freeze(new Set([FILE_TYPE, FILE_DIR_TYPE, ALL_TYPE]));
const DIR_TYPES = Object.freeze(new Set([DIR_TYPE, FILE_DIR_TYPE, ALL_TYPE]));
const READ_OPTIONS = Object.freeze({encoding: 'utf8'});

class ReaddirpStream extends Readable {
  static get defaultOptions() {
    return {
      root: '.',
      fileFilter: (path) => true,
      directoryFilter: (path) => true,
      type: 'files',
      lstat: false,
      depth: 2147483648
    }
  }

  constructor(options = {}) {
    super({objectMode: true, highWaterMark: 1});
    const opts = {...ReaddirpStream.defaultOptions, ...options};
    const {root} = opts;

    this._fileFilter = normalizeFilter(opts.fileFilter);
    this._directoryFilter = normalizeFilter(opts.directoryFilter);
    this._stat = opts.lstat ? lstat : stat;
    this._maxDepth = opts.depth;
    this._entryType = opts.type
    this._root = root;

    // Launch stream with one parent, the root dir.
    this.parents = [{parentPath: root, depth: 0}];
    this.filesToRead = 0;
  }

  async _read() {
    // If the stream was destroyed, we must not proceed.
    if (!this.readable) return;

    const parent = this.parents.pop();

    // All directories have been read...
    if (!parent) {
      // ...stop stream when there are no files to process.
      this._endStreamIfQueueIsEmpty();

      // ...we have files to process; but not directories.
      // hence, parent is undefined; and we cannot execute fs.readdir().
      // The files are being processed anywhere.
      return;
    }

    const {parentPath, depth} = parent;

    // To prevent race conditions, we increase counter while awaiting readdir.
    this.filesToRead++;
    let files;
    if (!parentPath) console.log("INVALID ARG", parentPath);

    try {
      files = await readdir(parentPath, READ_OPTIONS);
    } catch (error) {
      if (error.code === ENOENT) files = [];
      else throw error;
    }
    this.filesToRead--;

    // If the stream was destroyed, after readdir is completed
    if (!this.readable) return;

    this.filesToRead += files.length;

    for (const relativePath of files) {
      const fullPath = sysPath.resolve(sysPath.join(parentPath, relativePath));
      let stats;
      try {
        if (!fullPath) console.log('_stat', fullPath);
        stats = await this._stat(fullPath);
      } catch (error) {
        console.log(12312, error.code);

        if (error.code === ENOENT) {
          this.filesToRead--;
          continue;
        } else {
          throw error;
        }
      }
      if (!this.readable) return;
      const path = sysPath.relative(this._root, fullPath);
      const basename = sysPath.basename(path);

      /**
       * @type {EntryInfo}
       */
      const entry = {path, stats, fullPath, basename};

      if (this._isDirAndMatchesFilter(entry)) {
        this._pushNewParentIfLessThanMaxDepth(fullPath, depth + 1);
        this._emitPushIfUserWantsDir(entry);
        if (!this.isPaused()) this._read();
      } else if (this._isFileAndMatchesFilter(entry)) {
        this._emitPushIfUserWantsFile(entry);
      }
      this.filesToRead--;
    }

    this._endStreamIfQueueIsEmpty(parentPath);
  }

  _endStreamIfQueueIsEmpty(pp) {
    if (this.parents.length === 0 && this.filesToRead === 0 && this.readable) {
      this.push(null);
    }
  }

  _pushNewParentIfLessThanMaxDepth(parentPath, depth) {
    if (depth <= this._maxDepth) {
      this.parents.push({parentPath, depth});
      return true
    } else {
      return false;
    }
  }

  _isDirAndMatchesFilter(entry) {
    return entry.stats.isDirectory() && this._directoryFilter(entry);
  }

  _isFileAndMatchesFilter(entry) {
    const {stats} = entry;
    const isFileType = (
      (this._entryType === ALL_TYPE && !stats.isDirectory()) ||
      (stats.isFile() || stats.isSymbolicLink())
    );
    return isFileType && this._fileFilter(entry);
  }

  _emitPushIfUserWantsDir(entry) {
    if (DIR_TYPES.has(this._entryType)) {
      this._push(entry);
    }
  }

  _emitPushIfUserWantsFile(entry) {
    if (FILE_TYPES.has(this._entryType)) {
      this._push(entry);
    }
  }

  _push(entry) {
    if (this.readable) {
      this.push(entry);
    }
  }

  _handleError(error) {
    setImmediate(() => {
      this.emit('warn', error);
    });
  }

  _handleFatalError(error) {
    this.emit('error', error);
    this.destroy();

    setImmediate(() => {
      // this.emit('error', error);
      // this.destroy();
    });
  }

  destroy() {
    this.emit('close');
  }
}

/**
 * @typedef {Object} ReaddirpArguments
 * @property {Function=} fileFilter
 * @property {Function=} directoryFilter
 * @property {String=} type
 * @property {Number=} depth
 * @property {String=} root
 * @property {Boolean=} lstat
 */

/**
 * Main function which ends up calling readdirRec and reads all files and directories in given root recursively.
 * @param {String} root Root directory
 * @param {ReaddirpArguments=} options Options to specify root (start directory), filters and recursion depth
 */
const readdirp = (root, options = {}) => {
  let error;

  let type = options['entryType'] || options.type;
  if (type === 'both') type = FILE_DIR_TYPE;
  if (type) options.type = type;
  if (root == null || typeof root === 'undefined') {
    throw new Error('readdirp: root argument is required. Usage: readdirp(root, options)');
  } else if (typeof root !== 'string') {
    throw new Error(`readdirp: root argument must be a string. Usage: readdirp(root, options)`);
  } else if (type && !TYPES.includes(type)) {
    throw new Error(`readdirp: Invalid type passed. Use one of ${TYPES.join(', ')}`);
  }

  options.root = root;
  const stream = new ReaddirpStream(options);
  if (error) stream._handleFatalError(error);
  return stream;
};

const readdirpPromise = (root, options = {}) => {
  return new Promise((resolve, reject) => {
    const files = [];
    readdirp(root, options)
      .on('data', (entry) => { files.push(entry); })
      .on('end', () => { resolve(files); })
      .on('error', (error) => { reject(error); });
  });
};

readdirp.promise = readdirpPromise;
readdirp.ReaddirpStream = ReaddirpStream;
readdirp.default = readdirp;

module.exports = readdirp;
<commit_msg>466201.<commit_after>'use strict';

const fs = require('fs');
const {Readable} = require('stream');
const sysPath = require('path');
const {promisify} = require('util');
const picomatch = require('picomatch');
const readdir = promisify(fs.readdir);
const stat = promisify(fs.stat);
const lstat = promisify(fs.lstat);

/**
 * @typedef {Object} EntryInfo
 * @property {String} path
 * @property {String} fullPath
 * @property {fs.Stats} stats
 * @property {String} basename
 */

const BANG = '!';
const normalizeFilter = (filter) => {
  if (filter === undefined) return;
  if (typeof filter === "function") return filter;

  if (typeof filter === "string") {
    const glob = picomatch(filter.trim());
    return (entry) => glob(entry.basename);
  }

  if (Array.isArray(filter)) {
    const positive = [];
    const negative = [];
    for (const item of filter) {
      const trimmed = item.trim();
      if (trimmed.charAt(0) === BANG) {
        negative.push(picomatch(trimmed.slice(1)));
      } else {
        positive.push(picomatch(trimmed));
      }
    }

    if (negative.length > 0) {
      if (positive.length > 0) {
        return (entry) => positive.some(f => f(entry.basename)) &&
          !negative.every(f => f(entry.basename));
      } else {
        return (entry) => !negative.every(f => f(entry.basename));
      }
    } else {
      return (entry) => positive.some(f => f(entry.basename));
    }
  }
};

const ENOENT = 'ENOENT';
const FILE_TYPE = 'files';
const DIR_TYPE = 'directories';
const FILE_DIR_TYPE = 'files_directories';
const ALL_TYPE = 'all';
const TYPES = [FILE_TYPE, DIR_TYPE, FILE_DIR_TYPE, ALL_TYPE];
const FILE_TYPES = Object.freeze(new Set([FILE_TYPE, FILE_DIR_TYPE, ALL_TYPE]));
const DIR_TYPES = Object.freeze(new Set([DIR_TYPE, FILE_DIR_TYPE, ALL_TYPE]));
const READ_OPTIONS = Object.freeze({encoding: 'utf8'});

class ReaddirpStream extends Readable {
  static get defaultOptions() {
    return {
      root: '.',
      fileFilter: (path) => true,
      directoryFilter: (path) => true,
      type: 'files',
      lstat: false,
      depth: 2147483648
    }
  }

  constructor(options = {}) {
    super({objectMode: true, highWaterMark: 1});
    const opts = {...ReaddirpStream.defaultOptions, ...options};
    const {root} = opts;

    this._fileFilter = normalizeFilter(opts.fileFilter);
    this._directoryFilter = normalizeFilter(opts.directoryFilter);
    this._stat = opts.lstat ? lstat : stat;
    this._maxDepth = opts.depth;
    this._entryType = opts.type
    this._root = root;

    // Launch stream with one parent, the root dir.
    this.parents = [{parentPath: root, depth: 0}];
    this.filesToRead = 0;
  }

  async _read() {
    // If the stream was destroyed, we must not proceed.
    if (!this.readable) return;

    const parent = this.parents.pop();

    // All directories have been read...
    if (!parent) {
      // ...stop stream when there are no files to process.
      this._endStreamIfQueueIsEmpty();

      // ...we have files to process; but not directories.
      // hence, parent is undefined; and we cannot execute fs.readdir().
      // The files are being processed anywhere.
      return;
    }

    const {parentPath, depth} = parent;

    // To prevent race conditions, we increase counter while awaiting readdir.
    this.filesToRead++;
    let files;
    if (!parentPath) console.log("INVALID ARG", parentPath);

    try {
      files = await readdir(parentPath, READ_OPTIONS);
    } catch (error) {
      if (error.code === ENOENT) files = [];
      else throw error;
    }
    this.filesToRead--;

    // If the stream was destroyed, after readdir is completed
    if (!this.readable) return;

    this.filesToRead += files.length;

    for (const relativePath of files) {
      if (!this.readable) return;
      const fullPath = sysPath.resolve(sysPath.join(parentPath, relativePath));
      let stats;
      try {
        if (!fullPath) console.log('_stat', fullPath);
        stats = await this._stat(fullPath);
      } catch (error) {
        console.log(466201, error.code);

        if (error.code === ENOENT) {
          this.filesToRead--;
          continue;
        } else {
          throw error;
        }
      }
      if (!this.readable) return;
      const path = sysPath.relative(this._root, fullPath);
      const basename = sysPath.basename(path);

      /**
       * @type {EntryInfo}
       */
      const entry = {path, stats, fullPath, basename};

      if (this._isDirAndMatchesFilter(entry)) {
        this._pushNewParentIfLessThanMaxDepth(fullPath, depth + 1);
        this._emitPushIfUserWantsDir(entry);
        if (!this.isPaused()) this._read();
      } else if (this._isFileAndMatchesFilter(entry)) {
        this._emitPushIfUserWantsFile(entry);
      }
      this.filesToRead--;
    }

    this._endStreamIfQueueIsEmpty(parentPath);
  }

  _endStreamIfQueueIsEmpty(pp) {
    if (this.parents.length === 0 && this.filesToRead === 0 && this.readable) {
      this.push(null);
    }
  }

  _pushNewParentIfLessThanMaxDepth(parentPath, depth) {
    if (depth <= this._maxDepth) {
      this.parents.push({parentPath, depth});
      return true
    } else {
      return false;
    }
  }

  _isDirAndMatchesFilter(entry) {
    return entry.stats.isDirectory() && this._directoryFilter(entry);
  }

  _isFileAndMatchesFilter(entry) {
    const {stats} = entry;
    const isFileType = (
      (this._entryType === ALL_TYPE && !stats.isDirectory()) ||
      (stats.isFile() || stats.isSymbolicLink())
    );
    return isFileType && this._fileFilter(entry);
  }

  _emitPushIfUserWantsDir(entry) {
    if (DIR_TYPES.has(this._entryType)) {
      this._push(entry);
    }
  }

  _emitPushIfUserWantsFile(entry) {
    if (FILE_TYPES.has(this._entryType)) {
      this._push(entry);
    }
  }

  _push(entry) {
    if (this.readable) {
      this.push(entry);
    }
  }

  _handleError(error) {
    setImmediate(() => {
      this.emit('warn', error);
    });
  }

  _handleFatalError(error) {
    this.emit('error', error);
    this.destroy();

    setImmediate(() => {
      // this.emit('error', error);
      // this.destroy();
    });
  }

  destroy() {
    this.emit('close');
  }
}

/**
 * @typedef {Object} ReaddirpArguments
 * @property {Function=} fileFilter
 * @property {Function=} directoryFilter
 * @property {String=} type
 * @property {Number=} depth
 * @property {String=} root
 * @property {Boolean=} lstat
 */

/**
 * Main function which ends up calling readdirRec and reads all files and directories in given root recursively.
 * @param {String} root Root directory
 * @param {ReaddirpArguments=} options Options to specify root (start directory), filters and recursion depth
 */
const readdirp = (root, options = {}) => {
  let error;

  let type = options['entryType'] || options.type;
  if (type === 'both') type = FILE_DIR_TYPE;
  if (type) options.type = type;
  if (root == null || typeof root === 'undefined') {
    throw new Error('readdirp: root argument is required. Usage: readdirp(root, options)');
  } else if (typeof root !== 'string') {
    throw new Error(`readdirp: root argument must be a string. Usage: readdirp(root, options)`);
  } else if (type && !TYPES.includes(type)) {
    throw new Error(`readdirp: Invalid type passed. Use one of ${TYPES.join(', ')}`);
  }

  options.root = root;
  const stream = new ReaddirpStream(options);
  if (error) stream._handleFatalError(error);
  return stream;
};

const readdirpPromise = (root, options = {}) => {
  return new Promise((resolve, reject) => {
    const files = [];
    readdirp(root, options)
      .on('data', (entry) => { files.push(entry); })
      .on('end', () => { resolve(files); })
      .on('error', (error) => { reject(error); });
  });
};

readdirp.promise = readdirpPromise;
readdirp.ReaddirpStream = ReaddirpStream;
readdirp.default = readdirp;

module.exports = readdirp;
<|endoftext|>


<commit_before>/**
 * jstransformer-rework <https://github.com/tunnckoCore/jstransformer-rework>
 *
 * Copyright (c) 2015 Charlike Mike Reagent, contributors.
 * Released under the MIT license.
 */

'use strict';

var rework = require('rework');

exports.name = 'rework';
exports.outputFormat = 'css';

exports.render = function _render(str, opts, plugins) {
  plugins = plugins || [];
  plugins = Array.isArray(plugins) ? plugins : [plugins];

  var process = rework(str, opts);

  plugins.forEach(function(plugin) {
    process = process.use(plugin);
  });

  return process.toString(opts);
};
<commit_msg>add `inputFormats`<commit_after>/**
 * jstransformer-rework <https://github.com/tunnckoCore/jstransformer-rework>
 *
 * Copyright (c) 2015 Charlike Mike Reagent, contributors.
 * Released under the MIT license.
 */

'use strict';

var rework = require('rework');

exports.name = 'rework';
exports.inputFormats = ['css', 'rework'];
exports.outputFormat = 'css';

exports.render = function _render(str, opts, plugins) {
  plugins = plugins || [];
  plugins = Array.isArray(plugins) ? plugins : [plugins];

  var process = rework(str, opts);

  plugins.forEach(function(plugin) {
    process = process.use(plugin);
  });

  return process.toString(opts);
};
<|endoftext|>


<commit_before>const handlebars = require('handlebars');
const { DateTime } = require('luxon');
const semver = require('semver');
const mdTable = require('markdown-table');
const { logger } = require('../../../logger');
const { mergeChildConfig } = require('../../../config');

function ifTypesGroup(depNames, hasGroupName, branchUpgrades) {
  return (
    depNames.length === 2 &&
    !hasGroupName &&
    ((branchUpgrades[0].depName &&
      branchUpgrades[0].depName.startsWith('@types/') &&
      branchUpgrades[0].depName.endsWith(branchUpgrades[1].depName)) ||
      (branchUpgrades[1].depName &&
        branchUpgrades[1].depName.startsWith('@types/') &&
        branchUpgrades[1].depName.endsWith(branchUpgrades[0].depName)))
  );
}

function generateBranchConfig(branchUpgrades) {
  logger.debug(`generateBranchConfig(${branchUpgrades.length})`);
  logger.trace({ config: branchUpgrades });
  /** @type any */
  let config = {
    upgrades: [],
  };
  const hasGroupName = branchUpgrades[0].groupName !== null;
  logger.debug(`hasGroupName: ${hasGroupName}`);
  // Use group settings only if multiple upgrades or lazy grouping is disabled
  const depNames = [];
  const newValue = [];
  const toVersions = [];
  branchUpgrades.forEach(upg => {
    if (!depNames.includes(upg.depName)) {
      depNames.push(upg.depName);
    }
    if (!toVersions.includes(upg.toVersion)) {
      toVersions.push(upg.toVersion);
    }
    if (upg.commitMessageExtra) {
      const extra = handlebars.compile(upg.commitMessageExtra)(upg);
      if (!newValue.includes(extra)) {
        newValue.push(extra);
      }
    }
  });
  const groupEligible =
    depNames.length > 1 ||
    toVersions.length > 1 ||
    (!toVersions[0] && newValue.length > 1) ||
    branchUpgrades[0].lazyGrouping === false;
  if (newValue.length > 1 && !groupEligible) {
    // eslint-disable-next-line no-param-reassign
    branchUpgrades[0].commitMessageExtra = `to v${toVersions[0]}`;
  }
  logger.debug(`groupEligible: ${groupEligible}`);
  const useGroupSettings = hasGroupName && groupEligible;
  logger.debug(`useGroupSettings: ${useGroupSettings}`);
  let releaseTimestamp;
  for (const branchUpgrade of branchUpgrades) {
    let upgrade = { ...branchUpgrade };
    if (upgrade.currentDigest) {
      upgrade.currentDigestShort =
        upgrade.currentDigestShort ||
        upgrade.currentDigest.replace('sha256:', '').substring(0, 7);
    }
    if (upgrade.newDigest) {
      upgrade.newDigestShort =
        upgrade.newDigestShort ||
        upgrade.newDigest.replace('sha256:', '').substring(0, 7);
    }
    if (!upgrade.displayFrom) {
      if (upgrade.currentValue === upgrade.newValue) {
        upgrade.displayFrom =
          upgrade.currentDigestShort || upgrade.currentVersion || '';
        upgrade.displayTo =
          upgrade.displayTo ||
          upgrade.newDigestShort ||
          upgrade.newVersion ||
          '';
      } else {
        upgrade.displayFrom =
          upgrade.currentValue ||
          upgrade.currentVersion ||
          upgrade.currentDigestShort ||
          '';
        upgrade.displayTo =
          upgrade.displayTo ||
          upgrade.newValue ||
          upgrade.newVersion ||
          upgrade.newDigestShort ||
          '';
      }
    }

    if (
      upgrade.upgradeType !== 'lockFileMaintenance' &&
      upgrade.displayFrom.length * upgrade.displayTo.length === 0
    ) {
      logger.info({ config: upgrade }, 'empty displayFrom/displayTo');
    }
    if (upgrade.depName) {
      upgrade.depNameEscaped = (upgrade.lookupName || upgrade.depName).replace(
        /\//g,
        '%2f'
      );
    }
    upgrade.prettyDepType =
      upgrade.prettyDepType || upgrade.depType || 'dependency';
    if (useGroupSettings) {
      // Now overwrite original config with group config
      upgrade = mergeChildConfig(upgrade, upgrade.group);
      upgrade.isGroup = true;
    } else {
      delete upgrade.groupName;
    }
    // Delete group config regardless of whether it was applied
    delete upgrade.group;
    delete upgrade.lazyGrouping;

    const isTypesGroup = ifTypesGroup(depNames, hasGroupName, branchUpgrades);

    // istanbul ignore else
    if (toVersions.length > 1 && !isTypesGroup) {
      logger.debug({ toVersions });
      delete upgrade.commitMessageExtra;
      upgrade.recreateClosed = true;
    } else if (newValue.length > 1 && upgrade.isDigest) {
      logger.debug({ newValue });
      delete upgrade.commitMessageExtra;
      upgrade.recreateClosed = true;
    } else if (semver.valid(toVersions[0])) {
      upgrade.isRange = false;
    }
    // extract parentDir and baseDir from packageFile
    if (upgrade.packageFile) {
      const packagePath = upgrade.packageFile.split('/');
      if (packagePath.length > 0) {
        packagePath.splice(-1, 1);
      }
      if (packagePath.length > 0) {
        upgrade.parentDir = packagePath[packagePath.length - 1];
        upgrade.baseDir = packagePath.join('/');
      } else {
        upgrade.parentDir = '';
        upgrade.baseDir = '';
      }
    }
    // Use templates to generate strings
    logger.trace('Compiling branchName: ' + upgrade.branchName);
    upgrade.branchName = handlebars.compile(upgrade.branchName)(upgrade);
    if (upgrade.semanticCommits && !upgrade.commitMessagePrefix) {
      logger.debug('Upgrade has semantic commits enabled');
      let semanticPrefix = upgrade.semanticCommitType;
      if (upgrade.semanticCommitScope) {
        semanticPrefix += `(${handlebars.compile(upgrade.semanticCommitScope)(
          upgrade
        )})`;
      }
      upgrade.commitMessagePrefix = semanticPrefix;
      upgrade.commitMessagePrefix += semanticPrefix.endsWith(':') ? ' ' : ': ';
      upgrade.toLowerCase =
        upgrade.semanticCommitType.match(/[A-Z]/) === null &&
        !upgrade.semanticCommitType.startsWith(':');
    }
    // Compile a few times in case there are nested templates
    upgrade.commitMessage = handlebars.compile(upgrade.commitMessage || '')(
      upgrade
    );
    upgrade.commitMessage = handlebars.compile(upgrade.commitMessage)(upgrade);
    upgrade.commitMessage = handlebars.compile(upgrade.commitMessage)(upgrade);
    upgrade.commitMessage = upgrade.commitMessage.trim(); // Trim exterior whitespace
    upgrade.commitMessage = upgrade.commitMessage.replace(/\s+/g, ' '); // Trim extra whitespace inside string
    upgrade.commitMessage = upgrade.commitMessage.replace(
      /to vv(\d)/,
      'to v$1'
    );
    if (upgrade.toLowerCase) {
      // We only need to lowercvase the first line
      const splitMessage = upgrade.commitMessage.split('\n');
      splitMessage[0] = splitMessage[0].toLowerCase();
      upgrade.commitMessage = splitMessage.join('\n');
    }
    if (upgrade.commitBody) {
      upgrade.commitMessage = `${upgrade.commitMessage}\n\n${handlebars.compile(
        upgrade.commitBody
      )(upgrade)}`;
    }
    logger.trace(`commitMessage: ` + JSON.stringify(upgrade.commitMessage));
    if (upgrade.prTitle) {
      upgrade.prTitle = handlebars.compile(upgrade.prTitle)(upgrade);
      upgrade.prTitle = handlebars.compile(upgrade.prTitle)(upgrade);
      upgrade.prTitle = handlebars
        .compile(upgrade.prTitle)(upgrade)
        .trim()
        .replace(/\s+/g, ' ');
      if (upgrade.toLowerCase) {
        upgrade.prTitle = upgrade.prTitle.toLowerCase();
      }
    } else {
      [upgrade.prTitle] = upgrade.commitMessage.split('\n');
    }
    upgrade.prTitle += upgrade.hasBaseBranches ? ' ({{baseBranch}})' : '';
    if (upgrade.isGroup) {
      upgrade.prTitle +=
        upgrade.updateType === 'major' && upgrade.separateMajorMinor
          ? ' (major)'
          : '';
      upgrade.prTitle +=
        upgrade.updateType === 'minor' && upgrade.separateMinorPatch
          ? ' (minor)'
          : '';
      upgrade.prTitle += upgrade.updateType === 'patch' ? ' (patch)' : '';
    }
    // Compile again to allow for nested handlebars templates
    upgrade.prTitle = handlebars.compile(upgrade.prTitle)(upgrade);
    logger.debug(`prTitle: ` + JSON.stringify(upgrade.prTitle));
    config.upgrades.push(upgrade);
    if (upgrade.releaseTimestamp) {
      if (releaseTimestamp) {
        const existingStamp = DateTime.fromISO(releaseTimestamp);
        const upgradeStamp = DateTime.fromISO(upgrade.releaseTimestamp);
        if (upgradeStamp > existingStamp) {
          releaseTimestamp = upgrade.releaseTimestamp; // eslint-disable-line
        }
      } else {
        releaseTimestamp = upgrade.releaseTimestamp; // eslint-disable-line
      }
    }
  }
  if (
    depNames.length === 2 &&
    !hasGroupName &&
    config.upgrades[0].depName &&
    config.upgrades[0].depName.startsWith('@types/') &&
    config.upgrades[0].depName.endsWith(config.upgrades[1].depName)
  ) {
    logger.debug('Found @types - reversing upgrades to use depName in PR');
    config.upgrades.reverse();
    config.upgrades[0].recreateClosed = false;
    config.hasTypes = true;
  } else if (
    depNames.length === 2 &&
    !hasGroupName &&
    config.upgrades[1].depName &&
    config.upgrades[1].depName.startsWith('@types/') &&
    config.upgrades[1].depName.endsWith(config.upgrades[0].depName)
  ) {
    // do nothing
  } else {
    config.upgrades.sort((a, b) => {
      if (a.fileReplacePosition && b.fileReplacePosition) {
        // This is because we need to replace from the bottom of the file up
        return a.fileReplacePosition > b.fileReplacePosition ? -1 : 1;
      }
      if (a.depName < b.depName) return -1;
      if (a.depName > b.depName) return 1;
      return 0;
    });
  }
  // Now assign first upgrade's config as branch config
  config = { ...config, ...config.upgrades[0], releaseTimestamp };
  config.canBeUnpublished = config.upgrades.some(
    upgrade => upgrade.canBeUnpublished
  );
  config.reuseLockFiles = config.upgrades.every(
    upgrade => upgrade.updateType !== 'lockFileMaintenance'
  );
  config.masterIssueApproval = config.upgrades.some(
    upgrade => upgrade.masterIssueApproval
  );
  config.masterIssuePrApproval = config.upgrades.some(
    upgrade => upgrade.prCreation === 'approval'
  );
  config.automerge = config.upgrades.every(upgrade => upgrade.automerge);
  config.blockedByPin = config.upgrades.every(upgrade => upgrade.blockedByPin);
  const tableRows = config.upgrades
    .map(upgrade => getTableValues(upgrade))
    .filter(Boolean);
  if (tableRows.length) {
    let table = [];
    table.push(['datasource', 'package', 'from', 'to']);
    table = table.concat(tableRows);
    config.commitMessage += '\n\n' + mdTable(table) + '\n';
  }
  return config;
}

function getTableValues(upgrade) {
  if (!upgrade.commitBodyTable) {
    return null;
  }
  const {
    datasource,
    lookupName,
    depName,
    fromVersion,
    toVersion,
    displayFrom,
    displayTo,
  } = upgrade;
  const name = lookupName || depName;
  const from = fromVersion || displayFrom;
  const to = toVersion || displayTo;
  if (datasource && name && from && to) {
    return [datasource, name, from, to];
  }
  logger.debug(
    {
      datasource,
      lookupName,
      depName,
      fromVersion,
      toVersion,
      displayFrom,
      displayTo,
    },
    'Cannot determine table values'
  );
  return null;
}

module.exports = {
  generateBranchConfig,
};
<commit_msg>logs: trace branch generation<commit_after>const handlebars = require('handlebars');
const { DateTime } = require('luxon');
const semver = require('semver');
const mdTable = require('markdown-table');
const { logger } = require('../../../logger');
const { mergeChildConfig } = require('../../../config');

function ifTypesGroup(depNames, hasGroupName, branchUpgrades) {
  return (
    depNames.length === 2 &&
    !hasGroupName &&
    ((branchUpgrades[0].depName &&
      branchUpgrades[0].depName.startsWith('@types/') &&
      branchUpgrades[0].depName.endsWith(branchUpgrades[1].depName)) ||
      (branchUpgrades[1].depName &&
        branchUpgrades[1].depName.startsWith('@types/') &&
        branchUpgrades[1].depName.endsWith(branchUpgrades[0].depName)))
  );
}

function generateBranchConfig(branchUpgrades) {
  logger.debug(`generateBranchConfig(${branchUpgrades.length})`);
  logger.trace({ config: branchUpgrades });
  /** @type any */
  let config = {
    upgrades: [],
  };
  const hasGroupName = branchUpgrades[0].groupName !== null;
  logger.debug(`hasGroupName: ${hasGroupName}`);
  // Use group settings only if multiple upgrades or lazy grouping is disabled
  const depNames = [];
  const newValue = [];
  const toVersions = [];
  branchUpgrades.forEach(upg => {
    if (!depNames.includes(upg.depName)) {
      depNames.push(upg.depName);
    }
    if (!toVersions.includes(upg.toVersion)) {
      toVersions.push(upg.toVersion);
    }
    if (upg.commitMessageExtra) {
      const extra = handlebars.compile(upg.commitMessageExtra)(upg);
      if (!newValue.includes(extra)) {
        newValue.push(extra);
      }
    }
  });
  const groupEligible =
    depNames.length > 1 ||
    toVersions.length > 1 ||
    (!toVersions[0] && newValue.length > 1) ||
    branchUpgrades[0].lazyGrouping === false;
  if (newValue.length > 1 && !groupEligible) {
    // eslint-disable-next-line no-param-reassign
    branchUpgrades[0].commitMessageExtra = `to v${toVersions[0]}`;
  }
  logger.debug(`groupEligible: ${groupEligible}`);
  const useGroupSettings = hasGroupName && groupEligible;
  logger.debug(`useGroupSettings: ${useGroupSettings}`);
  let releaseTimestamp;
  for (const branchUpgrade of branchUpgrades) {
    let upgrade = { ...branchUpgrade };
    if (upgrade.currentDigest) {
      upgrade.currentDigestShort =
        upgrade.currentDigestShort ||
        upgrade.currentDigest.replace('sha256:', '').substring(0, 7);
    }
    if (upgrade.newDigest) {
      upgrade.newDigestShort =
        upgrade.newDigestShort ||
        upgrade.newDigest.replace('sha256:', '').substring(0, 7);
    }
    if (!upgrade.displayFrom) {
      if (upgrade.currentValue === upgrade.newValue) {
        upgrade.displayFrom =
          upgrade.currentDigestShort || upgrade.currentVersion || '';
        upgrade.displayTo =
          upgrade.displayTo ||
          upgrade.newDigestShort ||
          upgrade.newVersion ||
          '';
      } else {
        upgrade.displayFrom =
          upgrade.currentValue ||
          upgrade.currentVersion ||
          upgrade.currentDigestShort ||
          '';
        upgrade.displayTo =
          upgrade.displayTo ||
          upgrade.newValue ||
          upgrade.newVersion ||
          upgrade.newDigestShort ||
          '';
      }
    }

    if (
      upgrade.upgradeType !== 'lockFileMaintenance' &&
      upgrade.displayFrom.length * upgrade.displayTo.length === 0
    ) {
      logger.info({ config: upgrade }, 'empty displayFrom/displayTo');
    }
    if (upgrade.depName) {
      upgrade.depNameEscaped = (upgrade.lookupName || upgrade.depName).replace(
        /\//g,
        '%2f'
      );
    }
    upgrade.prettyDepType =
      upgrade.prettyDepType || upgrade.depType || 'dependency';
    if (useGroupSettings) {
      // Now overwrite original config with group config
      upgrade = mergeChildConfig(upgrade, upgrade.group);
      upgrade.isGroup = true;
    } else {
      delete upgrade.groupName;
    }
    // Delete group config regardless of whether it was applied
    delete upgrade.group;
    delete upgrade.lazyGrouping;

    const isTypesGroup = ifTypesGroup(depNames, hasGroupName, branchUpgrades);

    // istanbul ignore else
    if (toVersions.length > 1 && !isTypesGroup) {
      logger.trace({ toVersions });
      delete upgrade.commitMessageExtra;
      upgrade.recreateClosed = true;
    } else if (newValue.length > 1 && upgrade.isDigest) {
      logger.trace({ newValue });
      delete upgrade.commitMessageExtra;
      upgrade.recreateClosed = true;
    } else if (semver.valid(toVersions[0])) {
      upgrade.isRange = false;
    }
    // extract parentDir and baseDir from packageFile
    if (upgrade.packageFile) {
      const packagePath = upgrade.packageFile.split('/');
      if (packagePath.length > 0) {
        packagePath.splice(-1, 1);
      }
      if (packagePath.length > 0) {
        upgrade.parentDir = packagePath[packagePath.length - 1];
        upgrade.baseDir = packagePath.join('/');
      } else {
        upgrade.parentDir = '';
        upgrade.baseDir = '';
      }
    }
    // Use templates to generate strings
    logger.trace('Compiling branchName: ' + upgrade.branchName);
    upgrade.branchName = handlebars.compile(upgrade.branchName)(upgrade);
    if (upgrade.semanticCommits && !upgrade.commitMessagePrefix) {
      logger.trace('Upgrade has semantic commits enabled');
      let semanticPrefix = upgrade.semanticCommitType;
      if (upgrade.semanticCommitScope) {
        semanticPrefix += `(${handlebars.compile(upgrade.semanticCommitScope)(
          upgrade
        )})`;
      }
      upgrade.commitMessagePrefix = semanticPrefix;
      upgrade.commitMessagePrefix += semanticPrefix.endsWith(':') ? ' ' : ': ';
      upgrade.toLowerCase =
        upgrade.semanticCommitType.match(/[A-Z]/) === null &&
        !upgrade.semanticCommitType.startsWith(':');
    }
    // Compile a few times in case there are nested templates
    upgrade.commitMessage = handlebars.compile(upgrade.commitMessage || '')(
      upgrade
    );
    upgrade.commitMessage = handlebars.compile(upgrade.commitMessage)(upgrade);
    upgrade.commitMessage = handlebars.compile(upgrade.commitMessage)(upgrade);
    upgrade.commitMessage = upgrade.commitMessage.trim(); // Trim exterior whitespace
    upgrade.commitMessage = upgrade.commitMessage.replace(/\s+/g, ' '); // Trim extra whitespace inside string
    upgrade.commitMessage = upgrade.commitMessage.replace(
      /to vv(\d)/,
      'to v$1'
    );
    if (upgrade.toLowerCase) {
      // We only need to lowercvase the first line
      const splitMessage = upgrade.commitMessage.split('\n');
      splitMessage[0] = splitMessage[0].toLowerCase();
      upgrade.commitMessage = splitMessage.join('\n');
    }
    if (upgrade.commitBody) {
      upgrade.commitMessage = `${upgrade.commitMessage}\n\n${handlebars.compile(
        upgrade.commitBody
      )(upgrade)}`;
    }
    logger.trace(`commitMessage: ` + JSON.stringify(upgrade.commitMessage));
    if (upgrade.prTitle) {
      upgrade.prTitle = handlebars.compile(upgrade.prTitle)(upgrade);
      upgrade.prTitle = handlebars.compile(upgrade.prTitle)(upgrade);
      upgrade.prTitle = handlebars
        .compile(upgrade.prTitle)(upgrade)
        .trim()
        .replace(/\s+/g, ' ');
      if (upgrade.toLowerCase) {
        upgrade.prTitle = upgrade.prTitle.toLowerCase();
      }
    } else {
      [upgrade.prTitle] = upgrade.commitMessage.split('\n');
    }
    upgrade.prTitle += upgrade.hasBaseBranches ? ' ({{baseBranch}})' : '';
    if (upgrade.isGroup) {
      upgrade.prTitle +=
        upgrade.updateType === 'major' && upgrade.separateMajorMinor
          ? ' (major)'
          : '';
      upgrade.prTitle +=
        upgrade.updateType === 'minor' && upgrade.separateMinorPatch
          ? ' (minor)'
          : '';
      upgrade.prTitle += upgrade.updateType === 'patch' ? ' (patch)' : '';
    }
    // Compile again to allow for nested handlebars templates
    upgrade.prTitle = handlebars.compile(upgrade.prTitle)(upgrade);
    logger.trace(`prTitle: ` + JSON.stringify(upgrade.prTitle));
    config.upgrades.push(upgrade);
    if (upgrade.releaseTimestamp) {
      if (releaseTimestamp) {
        const existingStamp = DateTime.fromISO(releaseTimestamp);
        const upgradeStamp = DateTime.fromISO(upgrade.releaseTimestamp);
        if (upgradeStamp > existingStamp) {
          releaseTimestamp = upgrade.releaseTimestamp; // eslint-disable-line
        }
      } else {
        releaseTimestamp = upgrade.releaseTimestamp; // eslint-disable-line
      }
    }
  }
  if (
    depNames.length === 2 &&
    !hasGroupName &&
    config.upgrades[0].depName &&
    config.upgrades[0].depName.startsWith('@types/') &&
    config.upgrades[0].depName.endsWith(config.upgrades[1].depName)
  ) {
    logger.debug('Found @types - reversing upgrades to use depName in PR');
    config.upgrades.reverse();
    config.upgrades[0].recreateClosed = false;
    config.hasTypes = true;
  } else if (
    depNames.length === 2 &&
    !hasGroupName &&
    config.upgrades[1].depName &&
    config.upgrades[1].depName.startsWith('@types/') &&
    config.upgrades[1].depName.endsWith(config.upgrades[0].depName)
  ) {
    // do nothing
  } else {
    config.upgrades.sort((a, b) => {
      if (a.fileReplacePosition && b.fileReplacePosition) {
        // This is because we need to replace from the bottom of the file up
        return a.fileReplacePosition > b.fileReplacePosition ? -1 : 1;
      }
      if (a.depName < b.depName) return -1;
      if (a.depName > b.depName) return 1;
      return 0;
    });
  }
  // Now assign first upgrade's config as branch config
  config = { ...config, ...config.upgrades[0], releaseTimestamp };
  config.canBeUnpublished = config.upgrades.some(
    upgrade => upgrade.canBeUnpublished
  );
  config.reuseLockFiles = config.upgrades.every(
    upgrade => upgrade.updateType !== 'lockFileMaintenance'
  );
  config.masterIssueApproval = config.upgrades.some(
    upgrade => upgrade.masterIssueApproval
  );
  config.masterIssuePrApproval = config.upgrades.some(
    upgrade => upgrade.prCreation === 'approval'
  );
  config.automerge = config.upgrades.every(upgrade => upgrade.automerge);
  config.blockedByPin = config.upgrades.every(upgrade => upgrade.blockedByPin);
  const tableRows = config.upgrades
    .map(upgrade => getTableValues(upgrade))
    .filter(Boolean);
  if (tableRows.length) {
    let table = [];
    table.push(['datasource', 'package', 'from', 'to']);
    table = table.concat(tableRows);
    config.commitMessage += '\n\n' + mdTable(table) + '\n';
  }
  return config;
}

function getTableValues(upgrade) {
  if (!upgrade.commitBodyTable) {
    return null;
  }
  const {
    datasource,
    lookupName,
    depName,
    fromVersion,
    toVersion,
    displayFrom,
    displayTo,
  } = upgrade;
  const name = lookupName || depName;
  const from = fromVersion || displayFrom;
  const to = toVersion || displayTo;
  if (datasource && name && from && to) {
    return [datasource, name, from, to];
  }
  logger.debug(
    {
      datasource,
      lookupName,
      depName,
      fromVersion,
      toVersion,
      displayFrom,
      displayTo,
    },
    'Cannot determine table values'
  );
  return null;
}

module.exports = {
  generateBranchConfig,
};
<|endoftext|>


<commit_before>var debug = require('debug')('loopback-ds-paginate-mixin');
var utils = require('loopback-datasource-juggler/lib/utils');
var assert = require('assert');
var _ = require('lodash');

function Paginate(Model, config) {
  'use strict';

  var mixinName = 'Paginate';
  var modelName = Model.definition.name;
  var debugPrefix = mixinName + ': ' + modelName + ': ';
  debug(debugPrefix + 'Loading with config %o', config);

  Model.paginate = function(page, limit, query, cb) {
    cb = cb || utils.createPromiseCallback();

    // Check if page is passed otherwise default to 1
    if (_.isUndefined(page)) {
      debug(debugPrefix + 'paginate: page undefined: %s', page);
      page = 1;
    } else {
      debug(debugPrefix + 'paginate: page defined: %s', page);
    }

    // Check if limit is passed otherwise set to mixin config or default
    if (_.isUndefined(limit)) {
      limit = config.options.limit || 10;
    }

    // Do some assertions
    // TODO: These values should never be negative
    assert(typeof page, 'number', 'Page should always be a number');
    assert(typeof limit, 'number', 'Limit should always be a number');

    // Define the initial params object
    var params = {
      skip: (page - 1) * limit,
      limit: limit
    };

    // Check if additional query parameters are passed
    if (!_.isUndefined(query)) {

      // Check each of the following properties and add to params object
      var queryParams = ['fields', 'include', 'where', 'order'];
      queryParams.map(function(queryParam) {

        if (!_.isUndefined(query[queryParam])) {
          params[queryParam] = query[queryParam];

          debug(debugPrefix + 'paginate: adding param: %s = %o', queryParam,
            query[queryParam]);
        }
      });

    }

    debug(debugPrefix + 'paginate: params: %o', params);

    // Define where query used for counter
    var countWhere = params.where || {};

    // Get all the objects based on the params
    Model.all(params).then(function(items) {

      // Get total number of objects based on countWhere
      Model.count(countWhere).then(function(count) {

        // Format the result
        var result = {
          paging: {
            totalItems: count,
            totalPages: Math.ceil(count / limit),
            itemsPerPage: limit,
            currentPage: page
          },
          result: items
        };

        debug(debugPrefix + 'paginate: result: %o', result);
        cb(null, result);
      }).catch(cb);
    }).catch(cb);

    return cb.promise;
  };

  Model.remoteMethod('paginate', {
    accepts: [
      {arg: 'page', type: 'number'},
      {arg: 'limit', type: 'number'},
      {arg: 'query', type: 'object'}
    ],
    returns: {arg: 'result', type: 'string', root: true},
    http: {path: '/paginate', verb: 'get'}
  });

}

module.exports = function mixin(app) {
  app.loopback.modelBuilder.mixins.define('Paginate', Paginate);
};
<commit_msg>Enhance setting default parameters<commit_after>var debug = require('debug')('loopback-ds-paginate-mixin');
var utils = require('loopback-datasource-juggler/lib/utils');
var assert = require('assert');
var _ = require('lodash');

function Paginate(Model, options) {
  'use strict';

  var mixinName = 'Paginate';
  var modelName = Model.definition.name;
  var debugPrefix = mixinName + ': ' + modelName + ': ';
  debug(debugPrefix + 'Loading with config %o', options);

  Model.paginate = function(page, limit, query, cb) {
    cb = cb || utils.createPromiseCallback();

    // Check if page is passed otherwise default to 1
    if (!page) {
      debug(debugPrefix + 'paginate: page undefined:');
      page = 1;
    } else {
      debug(debugPrefix + 'paginate: page defined as: %s', page);
    }

    // Check if limit is passed otherwise set to mixin config or default
    if (!limit) {
      debug(debugPrefix + 'paginate: limit undefined:');
      limit = options.limit || 10;
    } else {
      debug(debugPrefix + 'paginate: limit defined as: %s', page);
    }

    // Do some assertions
    // TODO: These values should never be negative
    assert(typeof page, 'number', 'Page should always be a number');
    assert(typeof limit, 'number', 'Limit should always be a number');

    // Define the initial params object
    var params = {
      skip: (page - 1) * limit,
      limit: limit
    };

    // Check if additional query parameters are passed
    if (!_.isUndefined(query)) {

      // Check each of the following properties and add to params object
      var queryParams = ['fields', 'include', 'where', 'order'];
      queryParams.map(function(queryParam) {

        if (!_.isUndefined(query[queryParam])) {
          params[queryParam] = query[queryParam];

          debug(debugPrefix + 'paginate: adding param: %s = %o', queryParam,
            query[queryParam]);
        }
      });

    }

    debug(debugPrefix + 'paginate: params: %o', params);

    // Define where query used for counter
    var countWhere = params.where || {};

    // Get all the objects based on the params
    Model.all(params).then(function(items) {

      // Get total number of objects based on countWhere
      Model.count(countWhere).then(function(count) {

        // Format the result
        var result = {
          paging: {
            totalItems: count,
            totalPages: Math.ceil(count / limit),
            itemsPerPage: limit,
            currentPage: page
          },
          result: items
        };

        debug(debugPrefix + 'paginate: result: %o', result);
        cb(null, result);
      }).catch(cb);
    }).catch(cb);

    return cb.promise;
  };

  Model.remoteMethod('paginate', {
    accepts: [
      {arg: 'page', type: 'number'},
      {arg: 'limit', type: 'number'},
      {arg: 'query', type: 'object'}
    ],
    returns: {arg: 'result', type: 'string', root: true},
    http: {path: '/paginate', verb: 'get'}
  });

}

module.exports = function mixin(app) {
  app.loopback.modelBuilder.mixins.define('Paginate', Paginate);
};
<|endoftext|>


<commit_before>var through = require('through');
var EOL = '\n';

var LOOKUP = {
  'passed': 'text-success',
  'failed': 'text-danger',
  'undefined': 'text-warning',
  'skipped': 'text-muted'
};

module.exports = function (opts) {
  // We need to buffer =[
  var queue = [];
  var overall = [];

  var progress = {
    passed: 0,
    failed: 0,
    undefined: 0,
    skipped: 0
  };
  return {
    jadify: through(function (data) {
      var group = '';
      queue.push('section' + EOL);
      queue.push('  div.row' + EOL);
      queue.push('    div.col-md-offset-1.col-md-10' + EOL);
      queue.push('      article.col-md-offset-1.col-md-10' + EOL);
      queue.push('        div.panel.panel-default' + EOL);
      queue.push('          div.panel-heading' + EOL);
      queue.push('            a(href="'+data.id+'")' + EOL);
      queue.push('              h4.{color}#' + data.id + ' ' + data.keyword + ': ' + data.name + EOL);
      if (data.description) {
      queue.push('            p.h6 ' + data.description + EOL);
      }
      queue.push('          div.panel-body ' + EOL);
      data.elements.forEach(function (el, index, array) {
      queue.push('            article.row' + EOL);
      queue.push('              h4.col-md-12 ' + el.keyword + ': ' + el.name + EOL);
      el.steps.forEach(function (step) {
      queue.push('              div.col-sm-offset-3.col-sm-9' + EOL);
      queue.push('                h5.' + LOOKUP[step.result.status] + ' ' + step.keyword + step.name + EOL);
        progress[step.result.status]++;
        if (step.result.status === 'undefined' && group !== 'failed') {
          group = 'undefined';
        } else if (step.result.status === 'failed') {
          group = 'failed';
        } else if (step.result.status === 'skipped' && group !== 'undefined') {
          group = 'skipped';
        }
      });
      if (index !== array.length - 1) {
      queue.push('            hr' + EOL);
      }
      overall.push(group);
      });
      queue.push(EOL);
    }, function () {
      var total = Object.keys(progress).reduce(function (prev, curr) {
        return prev + progress[curr];
      }, 0);
      this.queue('mixin progress' + EOL);
      this.queue('  .progress' + EOL);
      this.queue('    .progress-bar.progress-bar-success(style="width: ' + (progress.passed / total) * 100 + '%")' + EOL);
      this.queue('    .progress-bar.progress-bar-danger(style="width: ' + (progress.failed / total) * 100 + '%")' + EOL);
      this.queue('    .progress-bar.progress-bar-warning(style="width: ' + (progress.undefined / total) * 100 + '%")' + EOL);
      this.queue('    .progress-bar.progress-bar-info(style="width: ' + (progress.skipped / total) * 100 + '%")' + EOL);
      if (opts.progress) {
        this.queue('+progress' + EOL);
      }
      if (opts.header) {
        this.queue('header.row' + EOL);
        this.queue('  h1.col-md-offset-2.col-md-10 ' + opts.header + EOL);
      }
      queue.forEach(function (item) {
        this.queue(item.replace('{color}', LOOKUP[overall.shift()]));
      }.bind(this));
    })
  };
};
<commit_msg>added the hashbang, might help..<commit_after>var through = require('through');
var EOL = '\n';

var LOOKUP = {
  'passed': 'text-success',
  'failed': 'text-danger',
  'undefined': 'text-warning',
  'skipped': 'text-muted'
};

module.exports = function (opts) {
  // We need to buffer =[
  var queue = [];
  var overall = [];

  var progress = {
    passed: 0,
    failed: 0,
    undefined: 0,
    skipped: 0
  };
  return {
    jadify: through(function (data) {
      var group = '';
      queue.push('section' + EOL);
      queue.push('  div.row' + EOL);
      queue.push('    div.col-md-offset-1.col-md-10' + EOL);
      queue.push('      article.col-md-offset-1.col-md-10' + EOL);
      queue.push('        div.panel.panel-default' + EOL);
      queue.push('          div.panel-heading' + EOL);
      queue.push('            a(href="#'+data.id+'")' + EOL);
      queue.push('              h4.{color}#' + data.id + ' ' + data.keyword + ': ' + data.name + EOL);
      if (data.description) {
      queue.push('            p.h6 ' + data.description + EOL);
      }
      queue.push('          div.panel-body ' + EOL);
      data.elements.forEach(function (el, index, array) {
      queue.push('            article.row' + EOL);
      queue.push('              h4.col-md-12 ' + el.keyword + ': ' + el.name + EOL);
      el.steps.forEach(function (step) {
      queue.push('              div.col-sm-offset-3.col-sm-9' + EOL);
      queue.push('                h5.' + LOOKUP[step.result.status] + ' ' + step.keyword + step.name + EOL);
        progress[step.result.status]++;
        if (step.result.status === 'undefined' && group !== 'failed') {
          group = 'undefined';
        } else if (step.result.status === 'failed') {
          group = 'failed';
        } else if (step.result.status === 'skipped' && group !== 'undefined') {
          group = 'skipped';
        }
      });
      if (index !== array.length - 1) {
      queue.push('            hr' + EOL);
      }
      overall.push(group);
      });
      queue.push(EOL);
    }, function () {
      var total = Object.keys(progress).reduce(function (prev, curr) {
        return prev + progress[curr];
      }, 0);
      this.queue('mixin progress' + EOL);
      this.queue('  .progress' + EOL);
      this.queue('    .progress-bar.progress-bar-success(style="width: ' + (progress.passed / total) * 100 + '%")' + EOL);
      this.queue('    .progress-bar.progress-bar-danger(style="width: ' + (progress.failed / total) * 100 + '%")' + EOL);
      this.queue('    .progress-bar.progress-bar-warning(style="width: ' + (progress.undefined / total) * 100 + '%")' + EOL);
      this.queue('    .progress-bar.progress-bar-info(style="width: ' + (progress.skipped / total) * 100 + '%")' + EOL);
      if (opts.progress) {
        this.queue('+progress' + EOL);
      }
      if (opts.header) {
        this.queue('header.row' + EOL);
        this.queue('  h1.col-md-offset-2.col-md-10 ' + opts.header + EOL);
      }
      queue.forEach(function (item) {
        this.queue(item.replace('{color}', LOOKUP[overall.shift()]));
      }.bind(this));
    })
  };
};
<|endoftext|>