<commit_before>/* -*- Mode: Javascript; js-indent-level: 2 -*- */

var async = require('async');
var naan = require('naan');
var _ = require('underscore');
var util = require('util');

module.exports = {
  /**
   * Create a new relationship between two nodes. Maps to
   * POST node/<startNodeId>/relationship
   */
  create: function(startNode, type, endNode, properties, callback) {
    if (typeof properties === 'function') {
      callback = properties;
      properties = null;
    }

    if (Array.isArray(startNode)) {
      var args = [ type, endNode, properties ];
      var createRel = naan.ecurry(this.rel.create, args, [1, 2, 3]);
      return this.throttleMap(startNode, createRel, callback);
    } else if (Array.isArray(endNode)) {
      var args = [ startNode, type, properties ];
      var createRel = naan.ecurry(this.rel.create, args, [0, 1, 3]);
      return this.throttleMap(endNode, createRel, callback);
    }

    var startNodeId = this._getId(startNode),
        endNodeId = this._getId(endNode);

    if (startNodeId == null || endNodeId == null) {
      return callback(new Error("Invalid ID"));
    }

    var request = {
      to: this._location('node', endNodeId),
      type: type,
    };

    if (properties) {
      request['data'] = properties;
    }

    var endpoint = util.format('node/%d/relationships', startNodeId);
    var op = this.operation(endpoint, 'POST', request);
    this.call(op, function(err, rel) {
      if (err) {
        callback(err);
      } else {
        callback(null, this._createRelationshipObject(rel));
      }
    });
  },

  /**
   * Update the properties of a given relationship. Maps to
   * POST relationship/<id>/properties
   */
  update: function(rel, callback) {
    if (Array.isArray(rel)) {
      return this.throttleMap(rel, this.rel.update, callback);
    }

    var id = this._getId(rel);

    if (id == null) {
      return callback(new Error("Invalid ID"));
    }

    var endpoint = util.format('relationship/%d/properties', id);
    var op = this.operation(endpoint, 'PUT', rel.properties);
    this.call(op, function(err) {
      callback(err);
    });
  },

  read: function(id, callback) {
    if (Array.isArray(id)) {
      return this.throttleMap(id, this.rel.read, callback);
    }

    id = this._getId(id);

    if (id == null) {
      return callback(new Error("Invalid ID"));
    }

    var endpoint = util.format('relationship/%d', id);
    var op = this.operation(endpoint);
    this.call(op, function(err, rel) {
      if (err) {
        callback(err);
      } else {
        callback(null, this._createRelationshipObject(rel));
      }
    });
  },

  delete: function(id, callback) {
    if (Array.isArray(id)) {
      return this.throttleMap(id, this.rel.delete, callback);
    }

    id = this._getId(id);

    if (id == null) {
      return callback(new Error("Invalid ID"));
    }

    var endpoint = util.format('relationship/%d', id);
    var op = this.operation(endpoint, 'DELETE');
    this.call(op, function(err, rel) {
      callback(err);
    });
  }
};
<commit_msg>Fixed incorrect code comment.<commit_after>/* -*- Mode: Javascript; js-indent-level: 2 -*- */

var async = require('async');
var naan = require('naan');
var _ = require('underscore');
var util = require('util');

module.exports = {
  /**
   * Create a new relationship between two nodes. Maps to
   * POST node/<startNodeId>/relationship
   */
  create: function(startNode, type, endNode, properties, callback) {
    if (typeof properties === 'function') {
      callback = properties;
      properties = null;
    }

    if (Array.isArray(startNode)) {
      var args = [ type, endNode, properties ];
      var createRel = naan.ecurry(this.rel.create, args, [1, 2, 3]);
      return this.throttleMap(startNode, createRel, callback);
    } else if (Array.isArray(endNode)) {
      var args = [ startNode, type, properties ];
      var createRel = naan.ecurry(this.rel.create, args, [0, 1, 3]);
      return this.throttleMap(endNode, createRel, callback);
    }

    var startNodeId = this._getId(startNode),
        endNodeId = this._getId(endNode);

    if (startNodeId == null || endNodeId == null) {
      return callback(new Error("Invalid ID"));
    }

    var request = {
      to: this._location('node', endNodeId),
      type: type,
    };

    if (properties) {
      request['data'] = properties;
    }

    var endpoint = util.format('node/%d/relationships', startNodeId);
    var op = this.operation(endpoint, 'POST', request);
    this.call(op, function(err, rel) {
      if (err) {
        callback(err);
      } else {
        callback(null, this._createRelationshipObject(rel));
      }
    });
  },

  /**
   * Update the properties of a given relationship. Maps to
   * PUT relationship/<id>/properties
   */
  update: function(rel, callback) {
    if (Array.isArray(rel)) {
      return this.throttleMap(rel, this.rel.update, callback);
    }

    var id = this._getId(rel);

    if (id == null) {
      return callback(new Error("Invalid ID"));
    }

    var endpoint = util.format('relationship/%d/properties', id);
    var op = this.operation(endpoint, 'PUT', rel.properties);
    this.call(op, function(err) {
      callback(err);
    });
  },

  read: function(id, callback) {
    if (Array.isArray(id)) {
      return this.throttleMap(id, this.rel.read, callback);
    }

    id = this._getId(id);

    if (id == null) {
      return callback(new Error("Invalid ID"));
    }

    var endpoint = util.format('relationship/%d', id);
    var op = this.operation(endpoint);
    this.call(op, function(err, rel) {
      if (err) {
        callback(err);
      } else {
        callback(null, this._createRelationshipObject(rel));
      }
    });
  },

  delete: function(id, callback) {
    if (Array.isArray(id)) {
      return this.throttleMap(id, this.rel.delete, callback);
    }

    id = this._getId(id);

    if (id == null) {
      return callback(new Error("Invalid ID"));
    }

    var endpoint = util.format('relationship/%d', id);
    var op = this.operation(endpoint, 'DELETE');
    this.call(op, function(err, rel) {
      callback(err);
    });
  }
};
<|endoftext|>


<commit_before>var noop = function () {};

module.exports = function requireHook (opts, cb) {
  if (typeof opts === 'function') {
    cb = opts;
    opts = {};
  }
  opts = opts || {};
  cb = cb || noop;

  var path = require('path');
  var remote = require('electron').remote;
  var Module = require('module');
  var syntaxError = require('syntax-error');
  var fs = remote.require('fs');
  var stripBOM = require('strip-bom');
  var combineSourceMap = require('combine-source-map');
  var browserResolve = require('browser-resolve');

  var entry = opts.entry;
  var basedir = opts.basedir || remote.process.cwd();

  var hasSetMain = false;
  var currentWrapFile = null;

  require.extensions['.js'] = function devtoolCompileModule (module, file) {
    // set the main module so that Node.js scripts run correctly
    if (!hasSetMain && entry && file === entry) {
      hasSetMain = true;
      process.mainModule = module;
    }

    var code = fs.readFileSync(file, 'utf8');
    try {
      currentWrapFile = file;
      module._compile(stripBOM(code), file);
      cb(null);
    } catch (err) {
      // improve Electron's error handling (i.e. SyntaxError)
      var realErr = syntaxError(code, file) || err;
      console.warn('Error compiling module: ' + file + '\n' + (realErr.annotated || realErr.message));
      console.error(err.stack);
      cb(err);
    }
  };

  // Include source maps for required modules
  var wrap = Module.wrap;
  Module.wrap = function devtoolWrapModule (script) {
    var original = script;
    var columnOffset = 0;
    if (opts.debugBreak && currentWrapFile === entry) {
      var debugExpr = 'debugger;';
      script = debugExpr + script;
      columnOffset = debugExpr.length;
    }
    var wrapScript = wrap.call(wrap, script);
    if (!currentWrapFile) return wrapScript;
    var sourceFile = path.relative(basedir, currentWrapFile)
      .replace(/\\/g, '/');
    var sourceRoot = basedir;
    var sourceMap = combineSourceMap.create(undefined, sourceRoot).addFile(
        { sourceFile: sourceFile, source: original },
        { line: 0, column: columnOffset });
    return [
      combineSourceMap.removeComments(wrapScript),
      sourceMap.comment()
    ].join('\n');
  };

  // Use browser field resolution for require statements
  if (opts.browserField) {
    var nativeResolve = Module._resolveFilename;
    Module._resolveFilename = function devtoolResolveFilename (filename, parent) {
      try {
        // Try to use a browser resolver first...
        return browserResolve.sync(filename, {
          filename: parent.filename,
          paths: parent.paths
        });
      } catch (e) {
        // Otherwise fall back to native; e.g. for Electron requires
        return nativeResolve.call(Module, filename, parent);
      }
    };
  }
};
<commit_msg>wrap closure on first line and original script on second; looks better on Windows<commit_after>var noop = function () {};

module.exports = function requireHook (opts, cb) {
  if (typeof opts === 'function') {
    cb = opts;
    opts = {};
  }
  opts = opts || {};
  cb = cb || noop;

  var path = require('path');
  var remote = require('electron').remote;
  var Module = require('module');
  var syntaxError = require('syntax-error');
  var fs = remote.require('fs');
  var stripBOM = require('strip-bom');
  var combineSourceMap = require('combine-source-map');
  var browserResolve = require('browser-resolve');

  var entry = opts.entry;
  var basedir = opts.basedir || remote.process.cwd();

  var hasSetMain = false;
  var currentWrapFile = null;

  require.extensions['.js'] = function devtoolCompileModule (module, file) {
    // set the main module so that Node.js scripts run correctly
    if (!hasSetMain && entry && file === entry) {
      hasSetMain = true;
      process.mainModule = module;
    }

    var code = fs.readFileSync(file, 'utf8');
    try {
      currentWrapFile = file;
      module._compile(stripBOM(code), file);
      cb(null);
    } catch (err) {
      // improve Electron's error handling (i.e. SyntaxError)
      var realErr = syntaxError(code, file) || err;
      console.warn('Error compiling module: ' + file + '\n' + (realErr.annotated || realErr.message));
      console.error(err.stack);
      cb(err);
    }
  };

  // Include source maps for required modules
  var wrap = Module.wrap;
  Module.wrap = function devtoolWrapModule (script) {
    var original = script;
    if (opts.debugBreak && currentWrapFile === entry) {
      script = 'debugger;' + script;
    }
    // On windows source maps are not showing. At least
    // this way we can move the original script on a
    // separate line from the Node closure.
    script = '\n' + script;
    var wrapScript = wrap.call(wrap, script);
    if (!currentWrapFile) return wrapScript;
    var sourceFile = path.relative(basedir, currentWrapFile)
      .replace(/\\/g, '/');
    var sourceRoot = basedir;
    var sourceMap = combineSourceMap.create(undefined, sourceRoot).addFile(
        { sourceFile: sourceFile, source: original },
        { line: 1 });
    return [
      combineSourceMap.removeComments(wrapScript),
      sourceMap.comment()
    ].join('\n');
  };

  // Use browser field resolution for require statements
  if (opts.browserField) {
    var nativeResolve = Module._resolveFilename;
    Module._resolveFilename = function devtoolResolveFilename (filename, parent) {
      try {
        // Try to use a browser resolver first...
        return browserResolve.sync(filename, {
          filename: parent.filename,
          paths: parent.paths
        });
      } catch (e) {
        // Otherwise fall back to native; e.g. for Electron requires
        return nativeResolve.call(Module, filename, parent);
      }
    };
  }
};
<|endoftext|>


<commit_before>// Built-in
var path = require('path');
var fs = require('fs');

// 3rd
var css = require('css');

// Custom
var constants = require('../constants');
var utils = require('../utils');
var Resolver = require('./resolver');
var ResourceTable = require('../resource/table');
var Package = require('../resource/package');
var parser = require('./cssParser');

var codeTree;

/**
 * Class deal with css resource
 * @constructor
 * @implements {Resolver}
 */
var StyleResolver = function() {
  this.options = SOI_CONFIG;
  // current resolving pkg in bundles.css's items.
  this.currentPkg = null;
};

utils.inherits(StyleResolver, Resolver);

/**
 * read all css files and concatenate them
 * helper function used by resolve method
 * @param {Array.<String>} cssFilesArray All css files' abs paths
 * @returns {string}
 */
StyleResolver.prototype.combo = function(cssFilesArray) {
    var content = '';
    cssFilesArray.forEach(function(path, i) {
        content += (i !== 0 ? '\n' : '') + codeTree[path];
    }, this);
    return content;
};

/**
 * According code tree write the file in array to a dist file.
 * @param {Array.<String>} cssFilesArray
 */
StyleResolver.prototype.write2compress = function(cssFilesArray) {
  var cssText = this.combo(cssFilesArray);
  var hex = utils.getStringHash(cssText).hex;
  var _csspath_ = this.currentPkg.dist_dir + '/' +
    path.basename(this.currentPkg.dist_file, constants.CSS_FILE_EXT) +
    constants.BUILD_FILENAME_CONNECTOR + hex + constants.CSS_FILE_EXT;

  var dir = path.dirname(_csspath_);
  if (!fs.existsSync(dir)) {
    fs.mkdirSync(dir);
  }
  utils.writeFile(_csspath_, cssText,
    { encoding: this.options.encoding });

  // register package
  var pkg = new Package({
    type    : 'css',
    input   : cssFilesArray[cssFilesArray.length - 1],
    files   : cssFilesArray,
    dist_file: _csspath_
  });
  ResourceTable.registerPackage({
    type    : 'css',
    key     : pkg.input,
    value   : pkg
  });

};

/**
 * calculate module dependency, combo and compress css files
 */
StyleResolver.prototype.resolve = function() {
  if (!this.options.bundles.css)
    return;

  this.options.bundles.css.forEach(function(pkg) {
    this.currentPkg = pkg;
    // If has `css_entry_point` means it's a self
    // dependency calculated code-style, @import used in
    // key file. If not present, we do nothing;
    if (pkg.input) {
      var cssFilesArray = parser.parse(pkg);
      codeTree = parser.getCodeTree();
      this.write2compress(cssFilesArray);
      parser.clear();
    } else {
      /*
      codeTree = {};
      var files = [];
      // generate code tree.
      pkg.files.forEach(function(file) {
        var p = path.resolve(this.options.base_dir, file);
        files.push(p);
        var content = utils.readFile(p, { encoding: this.options.encoding });
        var ast = css.parse(content);
        codeTree[p] = css.stringify(ast, { compress: true });
      }, this);
      this.write2compress(files);*/
    }
  }, this);
};

module.exports = StyleResolver;<commit_msg>rebuild fixed<commit_after>// Built-in
var path = require('path');
var fs = require('fs');

// 3rd
var css = require('css');

// Custom
var constants = require('../constants');
var utils = require('../utils');
var Resolver = require('./resolver');
var ResourceTable = require('../resource/table');
var Package = require('../resource/package');
var parser = require('./cssParser');

var codeTree;

/**
 * Class deal with css resource
 * @constructor
 * @implements {Resolver}
 */
var StyleResolver = function() {
  this.options = SOI_CONFIG;
  // current resolving pkg in bundles.css's items.
  this.currentPkg = null;
};

utils.inherits(StyleResolver, Resolver);

/**
 * read all css files and concatenate them
 * helper function used by resolve method
 * @param {Array.<String>} cssFilesArray All css files' abs paths
 * @returns {string}
 */
StyleResolver.prototype.combo = function(cssFilesArray) {
    var content = '';
    cssFilesArray.forEach(function(path, i) {
        content += (i !== 0 ? '\n' : '') + codeTree[path];
    }, this);
    return content;
};

/**
 * According code tree write the file in array to a dist file.
 * @param {Array.<String>} cssFilesArray
 */
StyleResolver.prototype.write2compress = function(cssFilesArray) {
  var cssText = this.combo(cssFilesArray);
  var hex = utils.getStringHash(cssText).hex;
  var _csspath_ = this.currentPkg.dist_dir + '/' +
    path.basename(this.currentPkg.dist_file, constants.CSS_FILE_EXT) +
    constants.BUILD_FILENAME_CONNECTOR + hex + constants.CSS_FILE_EXT;

  var dir = path.dirname(_csspath_);
  if (!fs.existsSync(dir)) {
    fs.mkdirSync(dir);
  }
  utils.writeFile(_csspath_, cssText,
    { encoding: this.options.encoding });

  // register package
  var pkg = new Package({
    type    : 'css',
    input   : cssFilesArray[cssFilesArray.length - 1],
    files   : cssFilesArray,
    dist_file: _csspath_
  });
  ResourceTable.registerPackage({
    type    : 'css',
    key     : pkg.input,
    value   : pkg
  });
};

/**
 * calculate module dependency, combo and compress css files
 */
StyleResolver.prototype.resolve = function() {
  if (!this.options.bundles.css)
    return;

  this.options.bundles.css.forEach(function(pkg) {
    this.currentPkg = pkg;
    // If has `css_entry_point` means it's a self
    // dependency calculated code-style, @import used in
    // key file. If not present, we do nothing;
    if (pkg.input) {
      var cssFilesArray = parser.parse(pkg);
      codeTree = parser.getCodeTree();
      this.write2compress(cssFilesArray);
      parser.clear();
    } else {
      /*
      codeTree = {};
      var files = [];
      // generate code tree.
      pkg.files.forEach(function(file) {
        var p = path.resolve(this.options.base_dir, file);
        files.push(p);
        var content = utils.readFile(p, { encoding: this.options.encoding });
        var ast = css.parse(content);
        codeTree[p] = css.stringify(ast, { compress: true });
      }, this);
      this.write2compress(files);*/
    }
  }, this);
};

module.exports = StyleResolver;<|endoftext|>


<commit_before>module.exports = makeRichMessage
module.exports.mergeMessages = mergeMessages

var emoji = require('markdown-it-emoji')
var ghlink = require('ghlink')
var higlight = require('highlight.js')
var htmlToVDom = require('html-to-vdom')
var MarkdownIt = require('markdown-it')
var twemoji = require('twemoji')
var util = require('./util.js')
var VNode = require('virtual-dom/vnode/vnode')
var VText = require('virtual-dom/vnode/vtext')

var md = new MarkdownIt({
  linkify: true,
  highlight: function (str, lang) {
    if (lang && higlight.getLanguage(lang)) {
      try {
        return higlight.highlight(lang, str).value
      } catch (err) {}
    }

    try {
      return higlight.highlightAuto(str).value
    } catch (err) {}

    return '' // use external default escaping
  }
}).use(emoji)

md.renderer.rules.emoji = function (token, index) {
  return twemoji.parse(token[index].content)
}

var convertHTML = htmlToVDom({
  VNode: VNode,
  VText: VText
})

function makeVDom (html) {
  return convertHTML('
' + html + '
')
}

function makeRichMessage (message, username) {
  message.anon = /Anonymous/i.test(message.username)
  message.avatar = message.anon
    ? 'static/cat.png'
    : 'https://github.com/' + message.username + '.png'
  message.timeago = util.timeago(message.timestamp)

  message.html = md.render(message.text)
  message.html = message.html.replace(/\n/g, '

')
  message.html = ghlink(message.html, { format: 'html' })
  message.html = message.html.replace(/(^| )(#[a-zA-Z0-9]+)( |$)$/g, '$1$2$3')

  var highlight = (message.text.indexOf(username) !== -1)
  var classStr = highlight ? ' class="highlight"' : ''
  message.html = '
' + message.html + '
'

  message.vdom = makeVDom(message.html)

  return message
}

function mergeMessages (message1, message2) {
  message1.text += '\n' + message2.text
  message1.html += '

' + message2.html
  message1.vdom = makeVDom(message1.html)
  return message1
}
<commit_msg>remove html to vdom conversion<commit_after>module.exports = makeRichMessage
module.exports.mergeMessages = mergeMessages

var emoji = require('markdown-it-emoji')
var ghlink = require('ghlink')
var higlight = require('highlight.js')
var MarkdownIt = require('markdown-it')
var twemoji = require('twemoji')
var util = require('./util.js')

var md = new MarkdownIt({
  linkify: true,
  highlight: function (str, lang) {
    if (lang && higlight.getLanguage(lang)) {
      try {
        return higlight.highlight(lang, str).value
      } catch (err) {}
    }

    try {
      return higlight.highlightAuto(str).value
    } catch (err) {}

    return '' // use external default escaping
  }
}).use(emoji)

md.renderer.rules.emoji = function (token, index) {
  return twemoji.parse(token[index].content)
}

function makeRichMessage (message, username) {
  message.anon = /Anonymous/i.test(message.username)
  message.avatar = message.anon
    ? 'static/cat.png'
    : 'https://github.com/' + message.username + '.png'
  message.timeago = util.timeago(message.timestamp)

  message.html = md.render(message.text)
  message.html = message.html.replace(/\n/g, '

')
  message.html = ghlink(message.html, { format: 'html' })
  message.html = message.html.replace(/(^| )(#[a-zA-Z0-9]+)( |$)$/g, '$1$2$3')

  var highlight = (message.text.indexOf(username) !== -1)
  var classStr = highlight ? ' class="highlight"' : ''
  message.html = '
' + message.html + '
'

  return message
}

function mergeMessages (message1, message2) {
  message1.text += '\n' + message2.text
  message1.html += '

' + message2.html
  return message1
}
<|endoftext|>


<commit_before>/*!
 * Express - Router
 * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var Route = require('./route')
  , Collection = require('./collection')
  , utils = require('../utils')
  , debug = require('debug')('express:router')
  , parse = require('url').parse;

/**
 * Expose `Router` constructor.
 */

exports = module.exports = Router;

/**
 * Expose HTTP methods.
 */

var methods = exports.methods = require('./methods');

/**
 * Initialize a new `Router` with the given `options`.
 *
 * @param {Object} options
 * @api private
 */

function Router(options) {
  options = options || {};
  var self = this;
  this.routes = new Collection;
  this.map = {};
  this.params = {};
  this._params = [];
  this.caseSensitive = options.caseSensitive;
  this.strict = options.strict;

  this.middleware = function router(req, res, next){
    self._dispatch(req, res, next);
  };
}

/**
 * Register a param callback `fn` for the given `name`.
 *
 * @param {String|Function} name
 * @param {Function} fn
 * @return {Router} for chaining
 * @api public
 */

Router.prototype.param = function(name, fn){
  // param logic
  if ('function' == typeof name) {
    this._params.push(name);
    return;
  }

  // apply param functions
  var params = this._params
    , len = params.length
    , ret;

  for (var i = 0; i < len; ++i) {
    if (ret = params[i](name, fn)) {
      fn = ret;
    }
  }

  // ensure we end up with a
  // middleware function
  if ('function' != typeof fn) {
    throw new Error('invalid param() call for ' + name + ', got ' + fn);
  }

  (this.params[name] = this.params[name] || []).push(fn);
  return this;
};

/**
 * Return a `Collection` of all routes defined.
 *
 * @return {Collection}
 * @api public
 */

Router.prototype.all = function(){
  return this.find(function(){
    return true;
  });
};

/**
 * Remove the given `route`, returns
 * a bool indicating if the route was present
 * or not.
 *
 * @param {Route} route
 * @return {Boolean}
 * @api public
 */

Router.prototype.remove = function(route){
  var routes = this.map[route.method]
    , len = routes.length;

  // remove from array
  var i = this.routes.indexOf(route);
  this.routes.splice(i, 1);

  // remove from map
  for (var i = 0; i < len; ++i) {
    if (route == routes[i]) {
      routes.splice(i, 1);
      return true;
    }
  }
};

/**
 * Return routes with route paths matching `path`.
 *
 * @param {String} method
 * @param {String} path
 * @return {Collection}
 * @api public
 */

Router.prototype.lookup = function(method, path){
  return this.find(function(route){
    return path == route.path
      && (route.method == method
      || method == 'all');
  });
};

// /**
//  * Return routes with regexps that match the given `url`.
//  *
//  * @param {String} method
//  * @param {String} url
//  * @return {Collection}
//  * @api public
//  */
//
// Router.prototype.match = function(method, url){
//   return this.find(function(route){
//     return route.match(url)
//       && (route.method == method
//       || method == 'all');
//   });
// };

/**
 * Find routes based on the return value of `fn`
 * which is invoked once per route.
 *
 * @param {Function} fn
 * @return {Collection}
 * @api public
 */

Router.prototype.find = function(fn){
  var len = methods.length
    , ret = new Collection(this)
    , method
    , routes
    , route;

  for (var i = 0; i < len; ++i) {
    method = methods[i];
    routes = this.map[method];
    if (!routes) continue;
    for (var j = 0, jlen = routes.length; j < jlen; ++j) {
      route = routes[j];
      if (fn(route)) ret.push(route);
    }
  }

  return ret;
};

/**
 * Route dispatcher aka the route "middleware".
 *
 * @param {IncomingMessage} req
 * @param {ServerResponse} res
 * @param {Function} next
 * @api private
 */

Router.prototype._dispatch = function(req, res, next){
  var params = this.params
    , self = this;

  debug('dispatching %s %s', req.method, req.url);

  // route dispatch
  (function pass(i, err){
    var paramCallbacks
      , paramIndex = 0
      , paramVal
      , route
      , keys
      , key
      , ret;

    // match next route
    function nextRoute(err) {
      pass(req._route_index + 1, err);
    }

    // match route
    req.route = route = self.match(req, i);

    // implied OPTIONS
    if (!route && 'OPTIONS' == req.method) return self._options(req, res);

    // no route
    if (!route) return next(err);
    debug('matched %s %s', route.method, route.path);

    // we have a route
    // start at param 0
    req.params = route.params;
    keys = route.keys;
    i = 0;

    // param callbacks
    function param(err) {
      paramIndex = 0;
      key = keys[i++];
      paramVal = key && req.params[key.name];
      paramCallbacks = key && params[key.name];

      try {
        if ('route' == err) {
          nextRoute();
        } else if (err) {
          i = 0;
          callbacks(err);
        } else if (paramCallbacks && undefined !== paramVal) {
          paramCallback();
        } else if (key) {
          param();
        } else {
          i = 0;
          callbacks();
        }
      } catch (err) {
        param(err);
      }
    };

    param(err);

    // single param callbacks
    function paramCallback(err) {
      var fn = paramCallbacks[paramIndex++];
      if (err || !fn) return param(err);
      fn(req, res, paramCallback, paramVal, key.name);
    }

    // invoke route callbacks
    function callbacks(err) {
      var fn = route.callbacks[i++];
      try {
        if ('route' == err) {
          nextRoute();
        } else if (err && fn) {
          if (fn.length < 4) return callbacks(err);
          fn(err, req, res, callbacks);
        } else if (fn) {
          fn(req, res, callbacks);
        } else {
          nextRoute(err);
        }
      } catch (err) {
        callbacks(err);
      }
    }
  })(0);
};

/**
 * Respond to __OPTIONS__ method.
 *
 * @param {IncomingMessage} req
 * @param {ServerResponse} res
 * @api private
 */

Router.prototype._options = function(req, res){
  var path = parse(req.url).pathname
    , body = this._optionsFor(path).join(',');
  res.set('Allow', body).send(body);
};

/**
 * Return an array of HTTP verbs or "options" for `path`.
 *
 * @param {String} path
 * @return {Array}
 * @api private
 */

Router.prototype._optionsFor = function(path){
  var self = this;
  return methods.filter(function(method){
    var routes = self.map[method];
    if (!routes || 'options' == method) return;
    for (var i = 0, len = routes.length; i < len; ++i) {
      if (routes[i].match(path)) return true;
    }
  }).map(function(method){
    return method.toUpperCase();
  });
};

/**
 * Attempt to match a route for `req`
 * with optional starting index of `i`
 * defaulting to 0.
 *
 * @param {IncomingMessage} req
 * @param {Number} i
 * @return {Route}
 * @api private
 */

Router.prototype.match = function(req, i, head){
  var method = req.method.toLowerCase()
    , url = parse(req.url)
    , path = url.pathname
    , routes = this.map
    , i = i || 0
    , captures
    , route
    , keys;

  // HEAD support
  // TODO: clean this up
  if (!head && 'head' == method) {
    // attempt lookup
    route = this.match(req, i, true);
    if (route) return route;

    // default to GET as res.render() / res.send()
    // etc support HEAD
     method = 'get';
  }

  // routes for this method
  if (routes = routes[method]) {

    // matching routes
    for (var len = routes.length; i < len; ++i) {
      route = routes[i];
      if (captures = route.match(path)) {
        keys = route.keys;
        route.params = [];

        // params from capture groups
        for (var j = 1, jlen = captures.length; j < jlen; ++j) {
          var key = keys[j-1]
            , val = 'string' == typeof captures[j]
              ? decodeURIComponent(captures[j])
              : captures[j];
          if (key) {
            route.params[key.name] = val;
          } else {
            route.params.push(val);
          }
        }

        // all done
        req._route_index = i;
        return route;
      }
    }
  }
};

/**
 * Route `method`, `path`, and one or more callbacks.
 *
 * @param {String} method
 * @param {String} path
 * @param {Function} callback...
 * @return {Router} for chaining
 * @api private
 */

Router.prototype.route = function(method, path, callbacks){
  var app = this.app
    , method = method.toLowerCase()
    , callbacks = utils.flatten([].slice.call(arguments, 2));

  // ensure path was given
  if (!path) throw new Error('Router#' + method + '() requires a path');

  // create the route
  debug('defined %s %s', method, path);
  var route = new Route(method, path, callbacks, {
      sensitive: this.caseSensitive
    , strict: this.strict
  });

  // add it
  (this.map[method] = this.map[method] || []).push(route);
  this.routes.push(route);
  return this;
};
<commit_msg>remove unused variable from Router.route<commit_after>/*!
 * Express - Router
 * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var Route = require('./route')
  , Collection = require('./collection')
  , utils = require('../utils')
  , debug = require('debug')('express:router')
  , parse = require('url').parse;

/**
 * Expose `Router` constructor.
 */

exports = module.exports = Router;

/**
 * Expose HTTP methods.
 */

var methods = exports.methods = require('./methods');

/**
 * Initialize a new `Router` with the given `options`.
 *
 * @param {Object} options
 * @api private
 */

function Router(options) {
  options = options || {};
  var self = this;
  this.routes = new Collection;
  this.map = {};
  this.params = {};
  this._params = [];
  this.caseSensitive = options.caseSensitive;
  this.strict = options.strict;

  this.middleware = function router(req, res, next){
    self._dispatch(req, res, next);
  };
}

/**
 * Register a param callback `fn` for the given `name`.
 *
 * @param {String|Function} name
 * @param {Function} fn
 * @return {Router} for chaining
 * @api public
 */

Router.prototype.param = function(name, fn){
  // param logic
  if ('function' == typeof name) {
    this._params.push(name);
    return;
  }

  // apply param functions
  var params = this._params
    , len = params.length
    , ret;

  for (var i = 0; i < len; ++i) {
    if (ret = params[i](name, fn)) {
      fn = ret;
    }
  }

  // ensure we end up with a
  // middleware function
  if ('function' != typeof fn) {
    throw new Error('invalid param() call for ' + name + ', got ' + fn);
  }

  (this.params[name] = this.params[name] || []).push(fn);
  return this;
};

/**
 * Return a `Collection` of all routes defined.
 *
 * @return {Collection}
 * @api public
 */

Router.prototype.all = function(){
  return this.find(function(){
    return true;
  });
};

/**
 * Remove the given `route`, returns
 * a bool indicating if the route was present
 * or not.
 *
 * @param {Route} route
 * @return {Boolean}
 * @api public
 */

Router.prototype.remove = function(route){
  var routes = this.map[route.method]
    , len = routes.length;

  // remove from array
  var i = this.routes.indexOf(route);
  this.routes.splice(i, 1);

  // remove from map
  for (var i = 0; i < len; ++i) {
    if (route == routes[i]) {
      routes.splice(i, 1);
      return true;
    }
  }
};

/**
 * Return routes with route paths matching `path`.
 *
 * @param {String} method
 * @param {String} path
 * @return {Collection}
 * @api public
 */

Router.prototype.lookup = function(method, path){
  return this.find(function(route){
    return path == route.path
      && (route.method == method
      || method == 'all');
  });
};

// /**
//  * Return routes with regexps that match the given `url`.
//  *
//  * @param {String} method
//  * @param {String} url
//  * @return {Collection}
//  * @api public
//  */
//
// Router.prototype.match = function(method, url){
//   return this.find(function(route){
//     return route.match(url)
//       && (route.method == method
//       || method == 'all');
//   });
// };

/**
 * Find routes based on the return value of `fn`
 * which is invoked once per route.
 *
 * @param {Function} fn
 * @return {Collection}
 * @api public
 */

Router.prototype.find = function(fn){
  var len = methods.length
    , ret = new Collection(this)
    , method
    , routes
    , route;

  for (var i = 0; i < len; ++i) {
    method = methods[i];
    routes = this.map[method];
    if (!routes) continue;
    for (var j = 0, jlen = routes.length; j < jlen; ++j) {
      route = routes[j];
      if (fn(route)) ret.push(route);
    }
  }

  return ret;
};

/**
 * Route dispatcher aka the route "middleware".
 *
 * @param {IncomingMessage} req
 * @param {ServerResponse} res
 * @param {Function} next
 * @api private
 */

Router.prototype._dispatch = function(req, res, next){
  var params = this.params
    , self = this;

  debug('dispatching %s %s', req.method, req.url);

  // route dispatch
  (function pass(i, err){
    var paramCallbacks
      , paramIndex = 0
      , paramVal
      , route
      , keys
      , key
      , ret;

    // match next route
    function nextRoute(err) {
      pass(req._route_index + 1, err);
    }

    // match route
    req.route = route = self.match(req, i);

    // implied OPTIONS
    if (!route && 'OPTIONS' == req.method) return self._options(req, res);

    // no route
    if (!route) return next(err);
    debug('matched %s %s', route.method, route.path);

    // we have a route
    // start at param 0
    req.params = route.params;
    keys = route.keys;
    i = 0;

    // param callbacks
    function param(err) {
      paramIndex = 0;
      key = keys[i++];
      paramVal = key && req.params[key.name];
      paramCallbacks = key && params[key.name];

      try {
        if ('route' == err) {
          nextRoute();
        } else if (err) {
          i = 0;
          callbacks(err);
        } else if (paramCallbacks && undefined !== paramVal) {
          paramCallback();
        } else if (key) {
          param();
        } else {
          i = 0;
          callbacks();
        }
      } catch (err) {
        param(err);
      }
    };

    param(err);

    // single param callbacks
    function paramCallback(err) {
      var fn = paramCallbacks[paramIndex++];
      if (err || !fn) return param(err);
      fn(req, res, paramCallback, paramVal, key.name);
    }

    // invoke route callbacks
    function callbacks(err) {
      var fn = route.callbacks[i++];
      try {
        if ('route' == err) {
          nextRoute();
        } else if (err && fn) {
          if (fn.length < 4) return callbacks(err);
          fn(err, req, res, callbacks);
        } else if (fn) {
          fn(req, res, callbacks);
        } else {
          nextRoute(err);
        }
      } catch (err) {
        callbacks(err);
      }
    }
  })(0);
};

/**
 * Respond to __OPTIONS__ method.
 *
 * @param {IncomingMessage} req
 * @param {ServerResponse} res
 * @api private
 */

Router.prototype._options = function(req, res){
  var path = parse(req.url).pathname
    , body = this._optionsFor(path).join(',');
  res.set('Allow', body).send(body);
};

/**
 * Return an array of HTTP verbs or "options" for `path`.
 *
 * @param {String} path
 * @return {Array}
 * @api private
 */

Router.prototype._optionsFor = function(path){
  var self = this;
  return methods.filter(function(method){
    var routes = self.map[method];
    if (!routes || 'options' == method) return;
    for (var i = 0, len = routes.length; i < len; ++i) {
      if (routes[i].match(path)) return true;
    }
  }).map(function(method){
    return method.toUpperCase();
  });
};

/**
 * Attempt to match a route for `req`
 * with optional starting index of `i`
 * defaulting to 0.
 *
 * @param {IncomingMessage} req
 * @param {Number} i
 * @return {Route}
 * @api private
 */

Router.prototype.match = function(req, i, head){
  var method = req.method.toLowerCase()
    , url = parse(req.url)
    , path = url.pathname
    , routes = this.map
    , i = i || 0
    , captures
    , route
    , keys;

  // HEAD support
  // TODO: clean this up
  if (!head && 'head' == method) {
    // attempt lookup
    route = this.match(req, i, true);
    if (route) return route;

    // default to GET as res.render() / res.send()
    // etc support HEAD
     method = 'get';
  }

  // routes for this method
  if (routes = routes[method]) {

    // matching routes
    for (var len = routes.length; i < len; ++i) {
      route = routes[i];
      if (captures = route.match(path)) {
        keys = route.keys;
        route.params = [];

        // params from capture groups
        for (var j = 1, jlen = captures.length; j < jlen; ++j) {
          var key = keys[j-1]
            , val = 'string' == typeof captures[j]
              ? decodeURIComponent(captures[j])
              : captures[j];
          if (key) {
            route.params[key.name] = val;
          } else {
            route.params.push(val);
          }
        }

        // all done
        req._route_index = i;
        return route;
      }
    }
  }
};

/**
 * Route `method`, `path`, and one or more callbacks.
 *
 * @param {String} method
 * @param {String} path
 * @param {Function} callback...
 * @return {Router} for chaining
 * @api private
 */

Router.prototype.route = function(method, path, callbacks){
  var method = method.toLowerCase()
    , callbacks = utils.flatten([].slice.call(arguments, 2));

  // ensure path was given
  if (!path) throw new Error('Router#' + method + '() requires a path');

  // create the route
  debug('defined %s %s', method, path);
  var route = new Route(method, path, callbacks, {
      sensitive: this.caseSensitive
    , strict: this.strict
  });

  // add it
  (this.map[method] = this.map[method] || []).push(route);
  this.routes.push(route);
  return this;
};
<|endoftext|>


<commit_before>/*
    Agora Forum Software
    Copyright (C) 2016 Gregory Sartucci
    License: AGPL-3.0, Check file LICENSE
*/

this.Schema || (this.Schema = {});

this.Schema.Post = new SimpleSchema({
    poster: {
        type: String,
        regEx: SimpleSchema.RegEx.Id,
        optional: true
    },
    summary: {
        type: String,
        optional: true,
        max: 100
    },
    content: {
        type: String,
        min: 1,
        max: 100000
    },
    inReplyTo: {
        type: String,
        regEx: SimpleSchema.RegEx.Id,
        optional: true,
        index: 1
    },
    tags: {
        type: Array,
        optional: true
    },
    'tags.$': {
        type: String,
        regEx: /(^|\s)([a-z\d][\w-]*)/i
    },
    replies: {
        type: Array,
        defaultValue: [],
        optional: true
    },
    'replies.$': {
        type: String,
        regEx: SimpleSchema.RegEx.Id
    },
    published: {
        type: Date,
        optional: true,
        index: 1
    },
    updated: {
        type: Date,
        optional: true
    }
});

this.Posts = new Mongo.Collection('posts');

this.Posts.attachSchema(this.Schema.Post);

this.Posts.before.insert(function(userId, post) {
    if (!post.poster && userId) post.poster = userId;
    post.published = Date.now();
});
<commit_msg>simplify schema<commit_after>/*
    Agora Forum Software
    Copyright (C) 2016 Gregory Sartucci
    License: AGPL-3.0, Check file LICENSE
*/

this.Schema || (this.Schema = {});

this.Schema.Post = new SimpleSchema({
    poster: {
        type: String,
        regEx: SimpleSchema.RegEx.Id,
        optional: true
    },
    summary: {
        type: String,
        optional: true,
        max: 100
    },
    content: {
        type: String,
        min: 1,
        max: 100000
    },
    inReplyTo: {
        type: String,
        regEx: SimpleSchema.RegEx.Id,
        optional: true,
        index: 1
    },
    tags: {
        type: [String],
        regEx: /(^|\s)([a-z\d][\w-]*)/i,
        optional: true
    },
    replies: {
        type: [String],
        regEx: SimpleSchema.RegEx.Id,
        defaultValue: [],
        optional: true
    },
    published: {
        type: Date,
        optional: true,
        index: 1
    },
    updated: {
        type: Date,
        optional: true
    }
});

this.Posts = new Mongo.Collection('posts');

this.Posts.attachSchema(this.Schema.Post);

this.Posts.before.insert(function(userId, post) {
    if (!post.poster && userId) post.poster = userId;
    post.published = Date.now();
});
<|endoftext|>


<commit_before>const SemanticolorView = require('./semanticolor-view');
const CompositeDisposable = require('atom').CompositeDisposable;
const SemanticolorGrammarFactory = require('./semanticolor-grammar');

const _ = require('lodash');
const Sugar = require('sugar');
const debug = require('debug')('semanticolor');

const fs = require('fs');
const path = require('path');

let lessFile = path.join(__dirname, '..', 'styles', 'semanticolor.less');
let grammarListFile = path.join(__dirname, 'grammars.txt');
let ignoredFileTypes = ['md', 'sh', 'cmd', 'bat', 'diff'];
let forceIncludeFileTypes = ['php', 'html', 'xml', 'vue'];

let grammars = {};
let options = ['contrast', 'mute', 'theme', 'colorize', 'defer'];
let config = {
	colorOptions: {
		description: 'Options that affect how colors are generated.',
		type: 'object',
		order: 0,
		properties: {
			hues: {
				type: 'integer',
				title: 'hues',
				description: 'Fewer colors may make them easier to distinguish, but they will be repeated more often.',
				minimum: 8,
				default: 700,
				maximum: 700,
				order: 1
			},
			saturation: {
				type: 'number',
				title: 'saturation',
				description: 'Color stauration (0 to 100%).',
				minimum: 0.1,
				default: 90,
				maximum: 100,
				order: 2
			},
			luminosity: {
				type: 'number',
				title: 'luminosity',
				description: 'Color luminosity (0 to 100%).',
				minimum: 0.1,
				default: 50,
				maximum: 100,
				order: 3
			},
			fade: {
				type: 'number',
				title: 'fade',
				description: 'Color fade (0 to 100%).',
				minimum: 0.1,
				default: 40,
				maximum: 100,
				order: 4
			}
		}
	}
};

let editorOptions = {
	type: 'object',
	description: 'Options that affect how colors are applied.',
	collapsed: true,
	properties: {
		enabled: {
			type: 'boolean',
			title: 'Enabled',
			default: 'true',
			order: 0
		},
		letiable: {
			type: 'string',
			title: 'Variables',
			default: 'colorize',
			enum: options,
			order: 1
		},
		comment: {
			type: 'string',
			title: 'Comments',
			default: 'contrast',
			enum: options,
			order: 2
		},
		primitive: {
			type: 'string',
			title: 'Primitives',
			default: 'mute',
			enum: options,
			order: 3
		},
		storage_modifier: {
			type: 'string',
			title: 'Storage modifiers',
			default: 'mute',
			enum: options,
			order: 4
		},
		storage_type: {
			type: 'string',
			title: 'Storage types',
			default: 'mute',
			enum: options,
			order: 5
		},
		support_type: {
			type: 'string',
			title: 'Support types',
			default: 'colorize',
			enum: options,
			order: 6
		},
		language: {
			type: 'string',
			title: 'Language elements',
			default: 'mute',
			enum: options,
			order: 7
		},
		keyword: {
			type: 'string',
			title: 'Keywords',
			default: 'mute',
			enum: options,
			order: 8
		},
		operator: {
			type: 'string',
			title: 'Operators',
			default: 'mute',
			enum: options,
			order: 9
		},
		punctuation: {
			type: 'string',
			title: 'Punctuation',
			default: 'defer',
			enum: options,
			order: 10
		},
		markup: {
			type: 'string',
			title: 'Markup',
			default: 'defer',
			enum: options,
			order: 11
		},
		string_quoted: {
			type: 'string',
			title: 'String constants',
			default: 'theme',
			enum: options,
			order: 12
		},
		regexp: {
			type: 'string',
			title: 'Regular expressions',
			default: 'theme',
			enum: options,
			order: 13
		},
		support_constant: {
			type: 'string',
			title: 'Support constants',
			default: 'theme',
			enum: options,
			order: 14
		},
		constant_numeric: {
			type: 'string',
			title: 'Numeric constants',
			default: 'theme',
			enum: options,
			order: 15
		},
		source: {
			type: 'string',
			title: 'Source',
			default: 'colorize',
			enum: options,
			order: 16
		},
		name: {
			type: 'string',
			title: 'Name',
			default: 'colorize',
			enum: options,
			order: 17
		},
		'attribute-name': {
			type: 'string',
			title: 'Attribute name',
			default: 'colorize',
			enum: options,
			order: 18
		},
		everythingElse: {
			type: 'string',
			title: 'Everything else',
			default: 'theme',
			enum: options,
			order: 19
		}
	}
};

let grammarList = [];
try {
	grammarList = Sugar.Array.compact(fs.readFileSync(grammarListFile, { encoding: 'utf-8' }).split(/\r\n|\r|\n/), true);
} catch (e) {
	grammarList = [];
}

for (let i = 0; i < grammarList.length; i++) {
	addGrammarToConfig(grammarList[i]);
}

function getGrammarName(grammar) {
	let result = grammar.name + ' (' + grammar.packageName + ')';
	return result;
}

function getGrammarParamNameFromGrammarName(grammarName) {
	return Sugar.String.camelize(Sugar.String.parameterize(grammarName), false);
}

function addGrammarToConfig(grammarName) {
	let options = Sugar.Object.clone(editorOptions);
	options.title = grammarName;
	config[getGrammarParamNameFromGrammarName(grammarName)] = options;
}

function writeGrammarListFile() {
	let fileContents = '';
	for (let i = 0; i < grammarList.length; i++) {
		fileContents += grammarList[i] + '\n';
	}
	fs.writeFileSync(grammarListFile, fileContents, { encoding: 'utf-8' });
}

let Semanticolor = {
	config: config,
	semanticolorView: SemanticolorView,
	modalPanel: SemanticolorView,
	disposables: new CompositeDisposable(),
	updateLessStylesheet: function(skipReload) {
		let cfg = atom.config.get('semanticolor').colorOptions;
		let less = makeLess(cfg.hues, cfg.saturation, cfg.luminosity, cfg.fade);
		let written = false;
		try {
			let currentLess = fs.readFileSync(lessFile, { encoding: 'utf-8' });
			if (currentLess !== less) {
				fs.writeFileSync(lessFile, less, { encoding: 'utf-8' });
				written = true;
			}
			if (written) {
				atom.notifications.addSuccess('Rewrote new colors...', {
					detail: 'Reloading with stylesheet of ' + cfg.hues + ' possible colors.'
				});
				if (!skipReload) {
					this.confirmReload();
				}
			}
		} catch (e) {
			atom.notifications.addError('No initial colors configured...', {
				detail: 'Updating stylesheet with default of ' + this.config.colorOptions.hues.default+
					' possible colors.'
			});
			try {
				less = makeLess(this.config.colorOptions.hues.default, this.config.colorOptions.saturation.default,
					this.config.colorOptions.luminosity.default, this.config.colorOptions.fade.default);
				written = fs.writeFileSync(lessFile, less, { encoding: 'utf-8' });
			} catch (err) {
				debug(err);
				atom.notifications.addError(e.code + ' : ' + e.message, {
					detail: 'Something failed. Open an issue with me!'
				});
			}
		}

		return written;

		function makeLess(hues, saturation, luminosity, fade) {
			return '@hues: ' + hues + ';\n' +
				'@saturation: ' + saturation + '%;\n' +
				'@luminosity: ' + luminosity + '%;\n' +
				'@fade: ' + fade + '%;';
		}
	},
	activate: function() {
		this.updateLessStylesheet(true);
		this.deactivated = false;
		this.semanticolorView = new SemanticolorView();
		let cfg = atom.config.get('semanticolor');
		for (let key in cfg) {
			if (key === 'colorOptions') {
				continue;
			}
			for (let scope in cfg[key]) {
				if (!editorOptions.properties[scope]) {
					delete cfg[key][scope];
				}
			}
		}
		atom.config.set('semanticolor', cfg);

		let temp = atom.grammars.getGrammars();
		for (let i = 0; i < temp.length; i++) {
			createGrammar(temp[i]);
		}

		atom.grammars.onDidAddGrammar(function(grammar) {
			// Don't bother on unload
			if (!atom.workspace) {
				return;
			}

			createGrammar(grammar);
			// Activate grammar on existing text editors with matching grammar
			atom.workspace.getTextEditors()
				.filter(editor => editor.getGrammar().name == grammar.name)
				.map(enable);
		});

		function createGrammar(grammar) {
			let paramName = tryAddGrammarToConfig(grammar);
			if (paramName && cfg[paramName].enabled) {
				grammars[paramName] = SemanticolorGrammarFactory.create(grammar, cfg[paramName], cfg.colorOptions.hues);
			}
		}

		function tryAddGrammarToConfig(grammar) {
			let grammarName = getGrammarName(grammar);
			let supported = isSupportedGrammar(grammar);
			let inGrammarList = grammarList.includes(grammarName);

			if (inGrammarList && supported) {
				return getGrammarParamNameFromGrammarName(grammarName);
			} else if (inGrammarList) {
				Sugar.Array.remove(grammarList, grammarName);
				writeGrammarListFile();
				debug('removed ' + grammarName, grammar);
				Semanticolor.confirmReload();
				return null;
			}

			if (supported) {
				grammarList.push(grammarName);
				writeGrammarListFile();
				debug('added ' + grammarName, grammar);
				Semanticolor.confirmReload();
			}
			return null;
		}

		function isSupportedGrammar(grammar) {
			let result = false;
			if (grammar.packageName !== SemanticolorGrammarFactory.packageName &&
				grammar.fileTypes.length > 0 &&
				((grammar.scopeName.includes('source') &&
						Sugar.Array.intersect(grammar.fileTypes, ignoredFileTypes).length == 0) ||
					Sugar.Array.intersect(grammar.fileTypes, forceIncludeFileTypes).length > 0)) {
				result = true;
			}
			return result;
		}

		this.disposables.add(atom.workspace.observeTextEditors(enable));

		this.disposables.add(atom.config.onDidChange('semanticolor', function(change) {
			if (Semanticolor.deactivated) return;
			_.debounce(function() {
				Semanticolor.updateLessStylesheet(change.newValue.colorOptions.hues === change.oldValue.colorOptions.hues);
				let reload = !Sugar.Object.isEqual(change.newValue.colorOptions.hues, change.oldValue.colorOptions.hues);
				for (let prop in change.newValue) {
					if (prop !== 'colorOptions' &&
						!Sugar.Object.isEqual(change.newValue[prop], change.oldValue[prop])) {
						reload = true;
						break;
					}
				}
				if (reload) {
					Semanticolor.confirmReload();
				}
			}, 1000)();
		}));

		function enable(editor) {
			let grammar = editor.getGrammar();
			let paramName = getGrammarParamNameFromGrammarName(getGrammarName(grammar));
			if (grammars[paramName]) {
				editor.setGrammar(grammars[paramName]);
			}
		}
	},

	confirmReload: function() {
		if (this.deactivated) {
			return;
		}
		this.modalPanel = atom.workspace.addModalPanel({
			item: this.semanticolorView.getElement(),
			visible: true
		});
	},

	deactivate: function() {
		this.deactivated = true;
		if (this.modalPanel && typeof this.modalPanel.destroy === 'function') {
			this.modalPanel.destroy();
		}
		let disposable = this.disposables;
		this.disposables = new CompositeDisposable();
		disposable.dispose();
		return this.semanticolorView.destroy();
	},
};

module.exports = Semanticolor;
<commit_msg>woops<commit_after>const SemanticolorView = require('./semanticolor-view');
const CompositeDisposable = require('atom').CompositeDisposable;
const SemanticolorGrammarFactory = require('./semanticolor-grammar');

const _ = require('lodash');
const Sugar = require('sugar');
const debug = require('debug')('semanticolor');

const fs = require('fs');
const path = require('path');

let lessFile = path.join(__dirname, '..', 'styles', 'semanticolor.less');
let grammarListFile = path.join(__dirname, 'grammars.txt');
let ignoredFileTypes = ['md', 'sh', 'cmd', 'bat', 'diff'];
let forceIncludeFileTypes = ['php', 'html', 'xml', 'vue'];

let grammars = {};
let options = ['contrast', 'mute', 'theme', 'colorize', 'defer'];
let config = {
	colorOptions: {
		description: 'Options that affect how colors are generated.',
		type: 'object',
		order: 0,
		properties: {
			hues: {
				type: 'integer',
				title: 'hues',
				description: 'Fewer colors may make them easier to distinguish, but they will be repeated more often.',
				minimum: 8,
				default: 700,
				maximum: 700,
				order: 1
			},
			saturation: {
				type: 'number',
				title: 'saturation',
				description: 'Color stauration (0 to 100%).',
				minimum: 0.1,
				default: 90,
				maximum: 100,
				order: 2
			},
			luminosity: {
				type: 'number',
				title: 'luminosity',
				description: 'Color luminosity (0 to 100%).',
				minimum: 0.1,
				default: 50,
				maximum: 100,
				order: 3
			},
			fade: {
				type: 'number',
				title: 'fade',
				description: 'Color fade (0 to 100%).',
				minimum: 0.1,
				default: 40,
				maximum: 100,
				order: 4
			}
		}
	}
};

let editorOptions = {
	type: 'object',
	description: 'Options that affect how colors are applied.',
	collapsed: true,
	properties: {
		enabled: {
			type: 'boolean',
			title: 'Enabled',
			default: 'true',
			order: 0
		},
		variable: {
			type: 'string',
			title: 'Variables',
			default: 'colorize',
			enum: options,
			order: 1
		},
		comment: {
			type: 'string',
			title: 'Comments',
			default: 'contrast',
			enum: options,
			order: 2
		},
		primitive: {
			type: 'string',
			title: 'Primitives',
			default: 'mute',
			enum: options,
			order: 3
		},
		storage_modifier: {
			type: 'string',
			title: 'Storage modifiers',
			default: 'mute',
			enum: options,
			order: 4
		},
		storage_type: {
			type: 'string',
			title: 'Storage types',
			default: 'mute',
			enum: options,
			order: 5
		},
		support_type: {
			type: 'string',
			title: 'Support types',
			default: 'colorize',
			enum: options,
			order: 6
		},
		language: {
			type: 'string',
			title: 'Language elements',
			default: 'mute',
			enum: options,
			order: 7
		},
		keyword: {
			type: 'string',
			title: 'Keywords',
			default: 'mute',
			enum: options,
			order: 8
		},
		operator: {
			type: 'string',
			title: 'Operators',
			default: 'mute',
			enum: options,
			order: 9
		},
		punctuation: {
			type: 'string',
			title: 'Punctuation',
			default: 'defer',
			enum: options,
			order: 10
		},
		markup: {
			type: 'string',
			title: 'Markup',
			default: 'defer',
			enum: options,
			order: 11
		},
		string_quoted: {
			type: 'string',
			title: 'String constants',
			default: 'theme',
			enum: options,
			order: 12
		},
		regexp: {
			type: 'string',
			title: 'Regular expressions',
			default: 'theme',
			enum: options,
			order: 13
		},
		support_constant: {
			type: 'string',
			title: 'Support constants',
			default: 'theme',
			enum: options,
			order: 14
		},
		constant_numeric: {
			type: 'string',
			title: 'Numeric constants',
			default: 'theme',
			enum: options,
			order: 15
		},
		source: {
			type: 'string',
			title: 'Source',
			default: 'colorize',
			enum: options,
			order: 16
		},
		name: {
			type: 'string',
			title: 'Name',
			default: 'colorize',
			enum: options,
			order: 17
		},
		'attribute-name': {
			type: 'string',
			title: 'Attribute name',
			default: 'colorize',
			enum: options,
			order: 18
		},
		everythingElse: {
			type: 'string',
			title: 'Everything else',
			default: 'theme',
			enum: options,
			order: 19
		}
	}
};

let grammarList = [];
try {
	grammarList = Sugar.Array.compact(fs.readFileSync(grammarListFile, { encoding: 'utf-8' }).split(/\r\n|\r|\n/), true);
} catch (e) {
	grammarList = [];
}

for (let i = 0; i < grammarList.length; i++) {
	addGrammarToConfig(grammarList[i]);
}

function getGrammarName(grammar) {
	let result = grammar.name + ' (' + grammar.packageName + ')';
	return result;
}

function getGrammarParamNameFromGrammarName(grammarName) {
	return Sugar.String.camelize(Sugar.String.parameterize(grammarName), false);
}

function addGrammarToConfig(grammarName) {
	let options = Sugar.Object.clone(editorOptions);
	options.title = grammarName;
	config[getGrammarParamNameFromGrammarName(grammarName)] = options;
}

function writeGrammarListFile() {
	let fileContents = '';
	for (let i = 0; i < grammarList.length; i++) {
		fileContents += grammarList[i] + '\n';
	}
	fs.writeFileSync(grammarListFile, fileContents, { encoding: 'utf-8' });
}

let Semanticolor = {
	config: config,
	semanticolorView: SemanticolorView,
	modalPanel: SemanticolorView,
	disposables: new CompositeDisposable(),
	updateLessStylesheet: function(skipReload) {
		let cfg = atom.config.get('semanticolor').colorOptions;
		let less = makeLess(cfg.hues, cfg.saturation, cfg.luminosity, cfg.fade);
		let written = false;
		try {
			let currentLess = fs.readFileSync(lessFile, { encoding: 'utf-8' });
			if (currentLess !== less) {
				fs.writeFileSync(lessFile, less, { encoding: 'utf-8' });
				written = true;
			}
			if (written) {
				atom.notifications.addSuccess('Rewrote new colors...', {
					detail: 'Reloading with stylesheet of ' + cfg.hues + ' possible colors.'
				});
				if (!skipReload) {
					this.confirmReload();
				}
			}
		} catch (e) {
			atom.notifications.addError('No initial colors configured...', {
				detail: 'Updating stylesheet with default of ' + this.config.colorOptions.hues.default+
					' possible colors.'
			});
			try {
				less = makeLess(this.config.colorOptions.hues.default, this.config.colorOptions.saturation.default,
					this.config.colorOptions.luminosity.default, this.config.colorOptions.fade.default);
				written = fs.writeFileSync(lessFile, less, { encoding: 'utf-8' });
			} catch (err) {
				debug(err);
				atom.notifications.addError(e.code + ' : ' + e.message, {
					detail: 'Something failed. Open an issue with me!'
				});
			}
		}

		return written;

		function makeLess(hues, saturation, luminosity, fade) {
			return '@hues: ' + hues + ';\n' +
				'@saturation: ' + saturation + '%;\n' +
				'@luminosity: ' + luminosity + '%;\n' +
				'@fade: ' + fade + '%;';
		}
	},
	activate: function() {
		this.updateLessStylesheet(true);
		this.deactivated = false;
		this.semanticolorView = new SemanticolorView();
		let cfg = atom.config.get('semanticolor');
		for (let key in cfg) {
			if (key === 'colorOptions') {
				continue;
			}
			for (let scope in cfg[key]) {
				if (!editorOptions.properties[scope]) {
					delete cfg[key][scope];
				}
			}
		}
		atom.config.set('semanticolor', cfg);

		let temp = atom.grammars.getGrammars();
		for (let i = 0; i < temp.length; i++) {
			createGrammar(temp[i]);
		}

		atom.grammars.onDidAddGrammar(function(grammar) {
			// Don't bother on unload
			if (!atom.workspace) {
				return;
			}

			createGrammar(grammar);
			// Activate grammar on existing text editors with matching grammar
			atom.workspace.getTextEditors()
				.filter(editor => editor.getGrammar().name == grammar.name)
				.map(enable);
		});

		function createGrammar(grammar) {
			let paramName = tryAddGrammarToConfig(grammar);
			if (paramName && cfg[paramName].enabled) {
				grammars[paramName] = SemanticolorGrammarFactory.create(grammar, cfg[paramName], cfg.colorOptions.hues);
			}
		}

		function tryAddGrammarToConfig(grammar) {
			let grammarName = getGrammarName(grammar);
			let supported = isSupportedGrammar(grammar);
			let inGrammarList = grammarList.includes(grammarName);

			if (inGrammarList && supported) {
				return getGrammarParamNameFromGrammarName(grammarName);
			} else if (inGrammarList) {
				Sugar.Array.remove(grammarList, grammarName);
				writeGrammarListFile();
				debug('removed ' + grammarName, grammar);
				Semanticolor.confirmReload();
				return null;
			}

			if (supported) {
				grammarList.push(grammarName);
				writeGrammarListFile();
				debug('added ' + grammarName, grammar);
				Semanticolor.confirmReload();
			}
			return null;
		}

		function isSupportedGrammar(grammar) {
			let result = false;
			if (grammar.packageName !== SemanticolorGrammarFactory.packageName &&
				grammar.fileTypes.length > 0 &&
				((grammar.scopeName.includes('source') &&
						Sugar.Array.intersect(grammar.fileTypes, ignoredFileTypes).length == 0) ||
					Sugar.Array.intersect(grammar.fileTypes, forceIncludeFileTypes).length > 0)) {
				result = true;
			}
			return result;
		}

		this.disposables.add(atom.workspace.observeTextEditors(enable));

		this.disposables.add(atom.config.onDidChange('semanticolor', function(change) {
			if (Semanticolor.deactivated) return;
			_.debounce(function() {
				Semanticolor.updateLessStylesheet(change.newValue.colorOptions.hues === change.oldValue.colorOptions.hues);
				let reload = !Sugar.Object.isEqual(change.newValue.colorOptions.hues, change.oldValue.colorOptions.hues);
				for (let prop in change.newValue) {
					if (prop !== 'colorOptions' &&
						!Sugar.Object.isEqual(change.newValue[prop], change.oldValue[prop])) {
						reload = true;
						break;
					}
				}
				if (reload) {
					Semanticolor.confirmReload();
				}
			}, 1000)();
		}));

		function enable(editor) {
			let grammar = editor.getGrammar();
			let paramName = getGrammarParamNameFromGrammarName(getGrammarName(grammar));
			if (grammars[paramName]) {
				editor.setGrammar(grammars[paramName]);
			}
		}
	},

	confirmReload: function() {
		if (this.deactivated) {
			return;
		}
		this.modalPanel = atom.workspace.addModalPanel({
			item: this.semanticolorView.getElement(),
			visible: true
		});
	},

	deactivate: function() {
		this.deactivated = true;
		if (this.modalPanel && typeof this.modalPanel.destroy === 'function') {
			this.modalPanel.destroy();
		}
		let disposable = this.disposables;
		this.disposables = new CompositeDisposable();
		disposable.dispose();
		return this.semanticolorView.destroy();
	},
};

module.exports = Semanticolor;
<|endoftext|>


<commit_before>'use strict';

var express = require('express');
var app = null;
var server = null;
var io = null;
var bodyParser = require('body-parser');
var fs = require('fs');
var path = require('path');
var EventEmitter = require('events').EventEmitter;
var authors = require('parse-authors');
var tokens = require('../login/tokens');
var authorizedSockets = {};

var configHelper = require('../config');
var config = configHelper.config;
var log = require('../logger')('nodecg/lib/server');
var bundles = require('../bundles');
var extensionManager;

// Check for updates
var request = require('request');
var versionCompare = require('../util').versionCompare;
var pjson = require('../../package.json');
request('http://registry.npmjs.org/nodecg/latest', function (err, res, body) {
    if (!err && res.statusCode === 200) {
        if (versionCompare(JSON.parse(body).version, pjson.version) >= 1) {
            log.warn('A new update is available for NodeCG: %s (current: %s)', JSON.parse(body).version, pjson.version);
        }
    }
});

module.exports = new EventEmitter();

module.exports.start = function() {
    log.info('Starting NodeCG %s (Running on Node.js %s)', pjson.version, process.version);

    // (Re)create Express app, HTTP(S) & Socket.IO servers
    app = express();

    if (config.ssl.enabled) {
        var sslOpts = {
            key: fs.readFileSync(config.ssl.keyPath),
            cert: fs.readFileSync(config.ssl.certificatePath)
        };

        // If we allow HTTP on the same port, use httpolyglot
        // otherwise, standard https server
        server = config.ssl.allowHTTP ?
            require('httpolyglot').createServer(sslOpts, app) :
            require('https').createServer(sslOpts, app);
    } else {
        server = require('http').createServer(app);
    }
    io = require('socket.io')(server);
    io.sockets.setMaxListeners(64); // Prevent console warnings when many extensions are installed

    extensionManager = require('./extensions.js');

    if (extensionManager.allLoaded) {
        doStart();
    } else {
        extensionManager.on('extensionsLoaded', doStart);
    }

    function doStart() {
        module.exports.emit('extensionsLoaded');

        // We intentionally wait until all bundles and extensions are loaded before starting the server.
        // This has two benefits:
        // 1) Prevents the dashboard/views from being opened before everything has finished loading
        // 2) Prevents dashboard/views from re-declaring replicants on reconnect before extensions have had a chance
        server.listen(config.listen);
        module.exports.emit('started');

        var protocol = config.ssl.enabled ? 'https' : 'http';
        log.info('NodeCG running on %s://%s', protocol, config.baseURL);
    }

    // Set up Express
    log.trace('Setting up Express');
    app.use(require('compression')());
    app.use('/components', express.static(path.join(__dirname, '..', '..', 'bower_components'),
        {maxAge: 60*60*24*7*1000}));
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({extended: true}));

    app.engine('jade', require('jade').__express);

    if (config.login.enabled) {
        log.info('Login security enabled');
        var login = require('../login');
        app.use(login);
        io.use(tokens.authorize());
    } else {
        app.get('/login*', function(req, res) {
            res.redirect('/dashboard');
        });
    }

    log.trace('Starting dashboard lib');
    var dashboard = require('../dashboard');
    app.use(dashboard);

    log.trace('Starting graphics lib');
    var graphics = require('../graphics');
    app.use(graphics);

    log.trace('Starting browser includes lib');
    var browserIncludes = require('../browser');
    app.use(browserIncludes);

    io.on('connection', function onConnection(socket) {
        log.trace('New socket connection: ID %s with IP %s', socket.id, socket.handshake.address);

        socket.on('message', function onMessage(data) {
            log.debug('Socket %s sent a message:', socket.id, data);
            io.emit('message', data);
        });

        socket.on('joinRoom', function onJoinRoom(room, cb) {
            log.debug('Socket %s requested to join room:', socket.id, room);
            if (typeof room !== 'string') {
                throw new Error('Room must be a string');
            }
            if (socket.rooms.indexOf(room) < 0) {
                socket.join(room);
            }
            if (typeof cb === 'function') {
                cb();
            }
        });

        socket.on('getBundleManifest', function onJoinRoom(bundleName, cb) {
            log.debug('Socket %s requested manifest for bundle %d:', socket.id, bundleName);
            if (typeof bundleName !== 'string') {
                var err = new Error('bundleName must be a string');
                cb(err);
            }

            if (typeof cb === 'function') {
                var bundle = bundles.find(bundleName);
                if (bundle) {
                    var manifest = JSON.parse(bundle.rawManifest);

                    if (manifest.author && typeof manifest.author === 'string') {
                        manifest.author = authors(manifest.author)[0];
                    }

                    if (manifest.contributors && Array.isArray(manifest.contributors)) {
                        manifest.contributors = authors(manifest.contributors.join('\n'));
                    }
                    cb(null, manifest);
                } else {
                    cb(null, null);
                }
            }
        });

        if (config.login.enabled) {
            var token = socket.token;
            if (!authorizedSockets.hasOwnProperty(token)) {
                authorizedSockets[token] = [];
            }

            if (authorizedSockets[token].indexOf(socket) < 0) {
                authorizedSockets[token].push(socket);
            }

            socket.on('disconnect', function() {
                // Sockets for this token might have already been invalidated
                if (authorizedSockets.hasOwnProperty(token)) {
                    var idx = authorizedSockets[token].indexOf(socket);
                    if (idx >= 0) {
                        authorizedSockets[token].splice(idx, 1);
                    }
                }
            });

            socket.on('regenerateToken', function onRegenerateToken(token, cb) {
                log.debug('Socket %s requested a new token:', socket.id);
                cb = cb || function(){};

                tokens.regenerate(token, function(err, newToken) {
                    if (err) {
                        log.error(err.stack);
                        cb(err);
                        return;
                    }

                    cb(null, newToken);

                    function invalidate() {
                        // Disconnect all sockets using this token
                        if (Array.isArray(authorizedSockets[token])) {
                            var sockets = authorizedSockets[token].slice(0);
                            sockets.forEach(function(socket) {
                                socket.error({
                                    message: 'This token has been invalidated',
                                    code: 'token_invalidated',
                                    type: 'UnauthorizedError'
                                });
                                socket.disconnect(true);
                            });
                        }
                    }

                    // TODO: Why is this on a timeout? If it's really needed, explain why.
                    setTimeout(invalidate, 500);
                });
            });
        }
    });

    log.trace('Attempting to listen on %s', config.listen);
    server.on('error', function(err) {
        switch (err.code) {
            case 'EADDRINUSE':
                log.error('[server.js] Listen %s in use, is NodeCG already running? NodeCG will now exit.',
                    config.listen);
                break;
            default:
                log.error('Unhandled error!', err);
                break;
        }

        module.exports.emit('error', err);
    });
};

module.exports.stop = function() {
    server.close();
    io.close();

    extensionManager = null;
    io = null;
    server = null;
    app = null;

    module.exports.emit('stopped');
};

module.exports.getExtensions = function() {
    if (extensionManager) {
        return extensionManager.getExtensions();
    }

    return {};
};

module.exports.getIO = function() {
    return io;
};

module.exports.mount = function (middleware) {
    app.use(middleware);
};
<commit_msg>no really, fix the tests. I insist.<commit_after>'use strict';

var express = require('express');
var app = null;
var server = null;
var io = null;
var bodyParser = require('body-parser');
var fs = require('fs');
var path = require('path');
var EventEmitter = require('events').EventEmitter;
var authors = require('parse-authors');
var tokens = require('../login/tokens');
var authorizedSockets = {};

var configHelper = require('../config');
var config = configHelper.config;
var log = require('../logger')('nodecg/lib/server');
var bundles = require('../bundles');
var extensionManager;

// Check for updates
var request = require('request');
var versionCompare = require('../util').versionCompare;
var pjson = require('../../package.json');
request('http://registry.npmjs.org/nodecg/latest', function (err, res, body) {
    if (!err && res.statusCode === 200) {
        if (versionCompare(JSON.parse(body).version, pjson.version) >= 1) {
            log.warn('A new update is available for NodeCG: %s (current: %s)', JSON.parse(body).version, pjson.version);
        }
    }
});

module.exports = new EventEmitter();

module.exports.start = function() {
    log.info('Starting NodeCG %s (Running on Node.js %s)', pjson.version, process.version);

    // (Re)create Express app, HTTP(S) & Socket.IO servers
    app = express();

    if (config.ssl && config.ssl.enabled) {
        var sslOpts = {
            key: fs.readFileSync(config.ssl.keyPath),
            cert: fs.readFileSync(config.ssl.certificatePath)
        };

        // If we allow HTTP on the same port, use httpolyglot
        // otherwise, standard https server
        server = config.ssl.allowHTTP ?
            require('httpolyglot').createServer(sslOpts, app) :
            require('https').createServer(sslOpts, app);
    } else {
        server = require('http').createServer(app);
    }
    io = require('socket.io')(server);
    io.sockets.setMaxListeners(64); // Prevent console warnings when many extensions are installed

    extensionManager = require('./extensions.js');

    if (extensionManager.allLoaded) {
        doStart();
    } else {
        extensionManager.on('extensionsLoaded', doStart);
    }

    function doStart() {
        module.exports.emit('extensionsLoaded');

        // We intentionally wait until all bundles and extensions are loaded before starting the server.
        // This has two benefits:
        // 1) Prevents the dashboard/views from being opened before everything has finished loading
        // 2) Prevents dashboard/views from re-declaring replicants on reconnect before extensions have had a chance
        server.listen(config.listen);
        module.exports.emit('started');

        var protocol = config.ssl.enabled ? 'https' : 'http';
        log.info('NodeCG running on %s://%s', protocol, config.baseURL);
    }

    // Set up Express
    log.trace('Setting up Express');
    app.use(require('compression')());
    app.use('/components', express.static(path.join(__dirname, '..', '..', 'bower_components'),
        {maxAge: 60*60*24*7*1000}));
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({extended: true}));

    app.engine('jade', require('jade').__express);

    if (config.login && config.login.enabled) {
        log.info('Login security enabled');
        var login = require('../login');
        app.use(login);
        io.use(tokens.authorize());
    } else {
        app.get('/login*', function(req, res) {
            res.redirect('/dashboard');
        });
    }

    log.trace('Starting dashboard lib');
    var dashboard = require('../dashboard');
    app.use(dashboard);

    log.trace('Starting graphics lib');
    var graphics = require('../graphics');
    app.use(graphics);

    log.trace('Starting browser includes lib');
    var browserIncludes = require('../browser');
    app.use(browserIncludes);

    io.on('connection', function onConnection(socket) {
        log.trace('New socket connection: ID %s with IP %s', socket.id, socket.handshake.address);

        socket.on('message', function onMessage(data) {
            log.debug('Socket %s sent a message:', socket.id, data);
            io.emit('message', data);
        });

        socket.on('joinRoom', function onJoinRoom(room, cb) {
            log.debug('Socket %s requested to join room:', socket.id, room);
            if (typeof room !== 'string') {
                throw new Error('Room must be a string');
            }
            if (socket.rooms.indexOf(room) < 0) {
                socket.join(room);
            }
            if (typeof cb === 'function') {
                cb();
            }
        });

        socket.on('getBundleManifest', function onJoinRoom(bundleName, cb) {
            log.debug('Socket %s requested manifest for bundle %d:', socket.id, bundleName);
            if (typeof bundleName !== 'string') {
                var err = new Error('bundleName must be a string');
                cb(err);
            }

            if (typeof cb === 'function') {
                var bundle = bundles.find(bundleName);
                if (bundle) {
                    var manifest = JSON.parse(bundle.rawManifest);

                    if (manifest.author && typeof manifest.author === 'string') {
                        manifest.author = authors(manifest.author)[0];
                    }

                    if (manifest.contributors && Array.isArray(manifest.contributors)) {
                        manifest.contributors = authors(manifest.contributors.join('\n'));
                    }
                    cb(null, manifest);
                } else {
                    cb(null, null);
                }
            }
        });

        if (config.login && config.login.enabled) {
            var token = socket.token;
            if (!authorizedSockets.hasOwnProperty(token)) {
                authorizedSockets[token] = [];
            }

            if (authorizedSockets[token].indexOf(socket) < 0) {
                authorizedSockets[token].push(socket);
            }

            socket.on('disconnect', function() {
                // Sockets for this token might have already been invalidated
                if (authorizedSockets.hasOwnProperty(token)) {
                    var idx = authorizedSockets[token].indexOf(socket);
                    if (idx >= 0) {
                        authorizedSockets[token].splice(idx, 1);
                    }
                }
            });

            socket.on('regenerateToken', function onRegenerateToken(token, cb) {
                log.debug('Socket %s requested a new token:', socket.id);
                cb = cb || function(){};

                tokens.regenerate(token, function(err, newToken) {
                    if (err) {
                        log.error(err.stack);
                        cb(err);
                        return;
                    }

                    cb(null, newToken);

                    function invalidate() {
                        // Disconnect all sockets using this token
                        if (Array.isArray(authorizedSockets[token])) {
                            var sockets = authorizedSockets[token].slice(0);
                            sockets.forEach(function(socket) {
                                socket.error({
                                    message: 'This token has been invalidated',
                                    code: 'token_invalidated',
                                    type: 'UnauthorizedError'
                                });
                                socket.disconnect(true);
                            });
                        }
                    }

                    // TODO: Why is this on a timeout? If it's really needed, explain why.
                    setTimeout(invalidate, 500);
                });
            });
        }
    });

    log.trace('Attempting to listen on %s', config.listen);
    server.on('error', function(err) {
        switch (err.code) {
            case 'EADDRINUSE':
                log.error('[server.js] Listen %s in use, is NodeCG already running? NodeCG will now exit.',
                    config.listen);
                break;
            default:
                log.error('Unhandled error!', err);
                break;
        }

        module.exports.emit('error', err);
    });
};

module.exports.stop = function() {
    server.close();
    io.close();

    extensionManager = null;
    io = null;
    server = null;
    app = null;

    module.exports.emit('stopped');
};

module.exports.getExtensions = function() {
    if (extensionManager) {
        return extensionManager.getExtensions();
    }

    return {};
};

module.exports.getIO = function() {
    return io;
};

module.exports.mount = function (middleware) {
    app.use(middleware);
};
<|endoftext|>


<commit_before>var app = require('../app')
  , client = require('./client')
  , config = require('./config')
  , derby = require('derby')
  , error = require('./error')
  , events = require('./events')
  , express = require('express')
  , expressApp = module.exports = express()
  , gravatar = require('derby-user-gravatar')
  , liveDbMongo = require('livedb-mongo')
  , MongoStore = require('connect-mongo')(express)
  , LocalStrategy = require('passport-local').Strategy
  , Providers = require('derby-user-providers')
  , racerBrowserChannel = require('racer-browserchannel')
  , racerHooks = require('racer-hooks')
  , Redis = require('redis')
  , User = require('derby-user');

var redis = Redis.createClient(config.get('redis.port'), config.get('redis.hostname'));
redis.select(config.get('redis.index'));

var store = derby.createStore({
  db: {db: liveDbMongo(config.get('mongo.uri') + '?auto_reconnect', config.get('mongo.options')), redis: redis}
});

var user = User(expressApp, {secretKey: config.get('secretKey')})
  , providers = Providers(expressApp, config.get('user'));

expressApp
  .use(express.favicon())
  .use(express.compress())
  .use(app.scripts(store))
  .use(express.static(__dirname + '/../../public'))
  .use(express.cookieParser())
  .use(express.session({
    secret: config.get('secretKey'),
    store: new MongoStore({
      safe: config.get('mongo.options.safe'),
      url: config.get('mongo.uri')
    })
  }))
  .use(racerBrowserChannel(store))
  .use(racerHooks(store))
  .use(store.modelMiddleware())
  .use(express.bodyParser())
  .use(express.methodOverride())
  .use(client())
  .use(user.init())
  .use(gravatar(store))
  .use(providers.init())
  .use(events(expressApp, store))
  .use(app.router())
  .use(expressApp.router)
  .use(user.routes())
  .use(providers.routes())
  .use(error(expressApp));<commit_msg>remove unused options<commit_after>var app = require('../app')
  , client = require('./client')
  , config = require('./config')
  , derby = require('derby')
  , error = require('./error')
  , events = require('./events')
  , express = require('express')
  , expressApp = module.exports = express()
  , gravatar = require('derby-user-gravatar')
  , liveDbMongo = require('livedb-mongo')
  , MongoStore = require('connect-mongo')(express)
  , LocalStrategy = require('passport-local').Strategy
  , Providers = require('derby-user-providers')
  , racerBrowserChannel = require('racer-browserchannel')
  , racerHooks = require('racer-hooks')
  , Redis = require('redis')
  , User = require('derby-user');

var redis = Redis.createClient(config.get('redis.port'), config.get('redis.hostname'));
redis.select(config.get('redis.index'));

var store = derby.createStore({
  db: {db: liveDbMongo(config.get('mongo.uri') + '?auto_reconnect', config.get('mongo.options')), redis: redis}
});

var user = User(expressApp)
  , providers = Providers(expressApp, config.get('user'));

expressApp
  .use(express.favicon())
  .use(express.compress())
  .use(app.scripts(store))
  .use(express.static(__dirname + '/../../public'))
  .use(express.cookieParser())
  .use(express.session({
    secret: config.get('secretKey'),
    store: new MongoStore({
      safe: config.get('mongo.options.safe'),
      url: config.get('mongo.uri')
    })
  }))
  .use(racerBrowserChannel(store))
  .use(racerHooks(store))
  .use(store.modelMiddleware())
  .use(express.bodyParser())
  .use(express.methodOverride())
  .use(client())
  .use(user.init())
  .use(gravatar(store))
  .use(providers.init())
  .use(events(expressApp, store))
  .use(app.router())
  .use(expressApp.router)
  .use(user.routes())
  .use(providers.routes())
  .use(error(expressApp));<|endoftext|>


<commit_before>const uuid  = require("uuid/v4");
const empty = require("is-empty");
const Ajv   = require("ajv");

const {
  asData
} = require("../utils/fun.js");

const RESERVED_ATTRIBUTES = {
  type: "type",
  specversion: "specversion",
  source: "source",
  id: "id",
  time: "time",
  dataschema: "schemaurl",
  datacontenttype: "datacontenttype",
  subject : "subject",
  data: "data",
  data_base64: "data_base64"
};

const schema = require("../../ext/spec_1.json");

const ajv = new Ajv({
  extendRefs: true
});

const isValidAgainstSchema = ajv.compile(schema);

function Spec1(_caller) {
  this.payload = {
    specversion: "1.0",
    id: uuid()
  };

  if(!_caller){
    _caller = require("../cloudevent.js");
  }

  /*
   * Used to inject compatibility methods or attributes
   */
  this.caller = _caller;

  // dataschema attribute
  this.caller.prototype.dataschema = function(dataschema){
    this.spec.dataschema(dataschema);
    return this;
  }
  this.caller.prototype.getDataschema = function() {
    return this.spec.getDataschema();
  }

  // datacontenttype attribute
  this.caller.prototype.dataContentType = function(contentType){
    this.spec.dataContentType(contentType);
    return this;
  };
  this.caller.prototype.getDataContentType = function(){
   return this.spec.getDataContentType();
  };

  // subject attribute
  this.caller.prototype.subject = function(_subject){
    this.spec.subject(_subject);
    return this;
  };
  this.caller.prototype.getSubject = function(){
   return this.spec.getSubject();
  };
}

/*
 * Check the spec constraints
 */
Spec1.prototype.check = function(ce){
  var toCheck = (!ce ? this.payload : ce);

  if(!isValidAgainstSchema(toCheck)) {
    throw {message: "invalid payload", errors: isValidAgainstSchema.errors};
  }
};

Spec1.prototype.id = function(_id){
  this.payload["id"] = _id;
  return this;
};

Spec1.prototype.getId = function() {
  return this.payload["id"];
};

Spec1.prototype.source = function(_source){
  this.payload["source"] = _source;
  return this;
};

Spec1.prototype.getSource = function() {
  return this.payload["source"];
};

Spec1.prototype.specversion = function(_specversion){
  // does not set! This is right
  return this;
};

Spec1.prototype.getSpecversion = function() {
  return this.payload["specversion"];
};

Spec1.prototype.type = function(_type){
  this.payload["type"] = _type;
  return this;
};

Spec1.prototype.getType = function(){
  return this.payload["type"];
};

Spec1.prototype.dataContentType = function(_contenttype){
  this.payload["datacontenttype"] = _contenttype;
  return this;
};
Spec1.prototype.getDataContentType = function() {
  return this.payload["datacontenttype"];
};

Spec1.prototype.dataschema = function(_schema){
  this.payload["dataschema"] = _schema;
  return this;
};
Spec1.prototype.getDataschema = function() {
  return this.payload["dataschema"];
};

Spec1.prototype.subject = function(_subject){
  this.payload["subject"] = _subject;
  return this;
};
Spec1.prototype.getSubject = function() {
  return this.payload["subject"];
};

Spec1.prototype.time = function(_time){
  this.payload["time"] = _time.toISOString();
  return this;
};
Spec1.prototype.getTime = function() {
  return this.payload["time"];
};

Spec1.prototype.data = function(_data){
  this.payload["data"] = _data;
  return this;
};
Spec1.prototype.getData = function() {
  let dct = this.payload["datacontenttype"];

  if(dct){
    this.payload["data"] = asData(this.payload["data"], dct);
  }

  return this.payload["data"];
};

Spec1.prototype.addExtension = function(key, value){
  if(!RESERVED_ATTRIBUTES.hasOwnProperty(key)){
    this.payload[key] = value;
  } else {
    throw {message: "Reserved attribute name: '" + key + "'"};
  }
  return this;
};

module.exports = Spec1;
<commit_msg>Validating extension types<commit_after>const uuid  = require("uuid/v4");
const empty = require("is-empty");
const Ajv   = require("ajv");
const URI   = require("uri-js");

const {
  asData,
  isBoolean,
  isInteger,
  isString,
  isDate,
  isBinary
} = require("../utils/fun.js");

const isValidType = (v) =>
  (isBoolean(v) || isInteger(v) || isString(v) || isDate(v) || isBinary(v));

const RESERVED_ATTRIBUTES = {
  type: "type",
  specversion: "specversion",
  source: "source",
  id: "id",
  time: "time",
  dataschema: "schemaurl",
  datacontenttype: "datacontenttype",
  subject : "subject",
  data: "data",
  data_base64: "data_base64"
};

const schema = require("../../ext/spec_1.json");

const ajv = new Ajv({
  extendRefs: true
});

const isValidAgainstSchema = ajv.compile(schema);

function Spec1(_caller) {
  this.payload = {
    specversion: "1.0",
    id: uuid()
  };

  if(!_caller){
    _caller = require("../cloudevent.js");
  }

  /*
   * Used to inject compatibility methods or attributes
   */
  this.caller = _caller;

  // dataschema attribute
  this.caller.prototype.dataschema = function(dataschema){
    this.spec.dataschema(dataschema);
    return this;
  }
  this.caller.prototype.getDataschema = function() {
    return this.spec.getDataschema();
  }

  // datacontenttype attribute
  this.caller.prototype.dataContentType = function(contentType){
    this.spec.dataContentType(contentType);
    return this;
  };
  this.caller.prototype.getDataContentType = function(){
   return this.spec.getDataContentType();
  };

  // subject attribute
  this.caller.prototype.subject = function(_subject){
    this.spec.subject(_subject);
    return this;
  };
  this.caller.prototype.getSubject = function(){
   return this.spec.getSubject();
  };
}

/*
 * Check the spec constraints
 */
Spec1.prototype.check = function(ce){
  var toCheck = (!ce ? this.payload : ce);

  if(!isValidAgainstSchema(toCheck)) {
    throw {message: "invalid payload", errors: isValidAgainstSchema.errors};
  }
};

Spec1.prototype.id = function(_id){
  this.payload["id"] = _id;
  return this;
};

Spec1.prototype.getId = function() {
  return this.payload["id"];
};

Spec1.prototype.source = function(_source){
  this.payload["source"] = _source;
  return this;
};

Spec1.prototype.getSource = function() {
  return this.payload["source"];
};

Spec1.prototype.specversion = function(_specversion){
  // does not set! This is right
  return this;
};

Spec1.prototype.getSpecversion = function() {
  return this.payload["specversion"];
};

Spec1.prototype.type = function(_type){
  this.payload["type"] = _type;
  return this;
};

Spec1.prototype.getType = function(){
  return this.payload["type"];
};

Spec1.prototype.dataContentType = function(_contenttype){
  this.payload["datacontenttype"] = _contenttype;
  return this;
};
Spec1.prototype.getDataContentType = function() {
  return this.payload["datacontenttype"];
};

Spec1.prototype.dataschema = function(_schema){
  this.payload["dataschema"] = _schema;
  return this;
};
Spec1.prototype.getDataschema = function() {
  return this.payload["dataschema"];
};

Spec1.prototype.subject = function(_subject){
  this.payload["subject"] = _subject;
  return this;
};
Spec1.prototype.getSubject = function() {
  return this.payload["subject"];
};

Spec1.prototype.time = function(_time){
  this.payload["time"] = _time.toISOString();
  return this;
};
Spec1.prototype.getTime = function() {
  return this.payload["time"];
};

Spec1.prototype.data = function(_data){
  this.payload["data"] = _data;
  return this;
};
Spec1.prototype.getData = function() {
  let dct = this.payload["datacontenttype"];

  if(dct){
    this.payload["data"] = asData(this.payload["data"], dct);
  }

  return this.payload["data"];
};

Spec1.prototype.addExtension = function(key, value){
  if(!RESERVED_ATTRIBUTES.hasOwnProperty(key)){
    if(isValidType(value)){
      this.payload[key] = value;
    } else {
      throw {message: "Invalid type of extension value"};
    }
  } else {
    throw {message: "Reserved attribute name: '" + key + "'"};
  }
  return this;
};

module.exports = Spec1;
<|endoftext|>


<commit_before>'use strict';

var forEachRight = require('es5-ext/lib/Array/prototype/for-each-right')
  , forEach      = require('es5-ext/lib/Object/for-each')
  , serialize    = require('../_internals/serialize')
  , signals      = require('../_internals/signal')

  , stringify = JSON.stringify;

module.exports = exports = function () {
	var done = {}, data = [];
	forEach(signals, function (signal, signalId) {
		forEachRight.call(signal._order, function (objId) {
			if (done[objId]) return;
			done[objId] = true;
			data.push([signal._sourceId, signal._stamp, objId,
				serialize(signal[objId])]);
		});
	}, null, function (a, b) {
		return this[b]._stamp - this[a]._stamp;
	});

	return data.reverse();
};

exports.code = function () {
	return '\'use strict\';\n\n' +
		'var import = require(\'dbjs/lib/_internals/signal-import\');\n\n' +
		exports().map(function (data) {
			return 'import(' + stringify(data[0]) + ', ' + data[1] + ', ' +
				stringify(data[2]) + ', ' + stringify(data[3]) + ');';
		}).join('\n') + '\n';
};
<commit_msg>Fix var name<commit_after>'use strict';

var forEachRight = require('es5-ext/lib/Array/prototype/for-each-right')
  , forEach      = require('es5-ext/lib/Object/for-each')
  , serialize    = require('../_internals/serialize')
  , signals      = require('../_internals/signal')

  , stringify = JSON.stringify;

module.exports = exports = function () {
	var done = {}, data = [];
	forEach(signals, function (signal, signalId) {
		forEachRight.call(signal._order, function (objId) {
			if (done[objId]) return;
			done[objId] = true;
			data.push([signal._sourceId, signal._stamp, objId,
				serialize(signal[objId])]);
		});
	}, null, function (a, b) {
		return this[b]._stamp - this[a]._stamp;
	});

	return data.reverse();
};

exports.code = function () {
	return '\'use strict\';\n\n' +
		'var dbImport = require(\'dbjs/lib/_internals/signal-import\');\n\n' +
		exports().map(function (data) {
			return 'dbImport(' + stringify(data[0]) + ', ' + data[1] + ', ' +
				stringify(data[2]) + ', ' + stringify(data[3]) + ');';
		}).join('\n') + '\n';
};
<|endoftext|>


<commit_before>'use strict';

var forEachRight = require('es5-ext/lib/Array/prototype/for-each-right')
  , forEach      = require('es5-ext/lib/Object/for-each')
  , serialize    = require('../_internals/serialize')
  , signals      = require('../_internals/signal')

  , stringify = JSON.stringify;

module.exports = exports = function () {
	var done = {}, data = [];
	forEach(signals, function (signal, signalId) {
		forEachRight.call(signal._order, function (objId) {
			if (done[objId]) return;
			done[objId] = true;
			data.push([signal._sourceId, signal._stamp, objId,
				serialize(signal[objId])]);
		});
	}, null, function (a, b) {
		return this[b]._stamp - this[a]._stamp;
	});

	return data.reverse();
};

exports.code = function () {
	return '\'use strict\';\n\n' +
		'var dbImport = require(\'dbjs/lib/_internals/signal-import\');\n\n' +
		exports().map(function (data) {
			return 'dbImport(' + stringify(data[0]) + ', ' + data[1] + ', ' +
				stringify(data[2]) + ', ' + stringify(data[3]) + ');';
		}).join('\n') + '\n';
};
<commit_msg>Fix export of namespace values<commit_after>'use strict';

var forEachRight = require('es5-ext/lib/Array/prototype/for-each-right')
  , forEach      = require('es5-ext/lib/Object/for-each')
  , contains     = require('es5-ext/lib/String/prototype/contains')
  , serialize    = require('../_internals/serialize')
  , signals      = require('../_internals/signal')

  , stringify = JSON.stringify;

module.exports = exports = function () {
	var done = {}, data = [];
	forEach(signals, function (signal, signalId) {
		forEachRight.call(signal._order, function (objId) {
			if (done[objId]) return;
			done[objId] = true;
			data.push([signal._sourceId, signal._stamp, objId,
				contains.call(objId, ':') ? serialize(signal[objId]) :
				signal[objId]._id_]);
		});
	}, null, function (a, b) {
		return this[b]._stamp - this[a]._stamp;
	});

	return data.reverse();
};

exports.code = function () {
	return '\'use strict\';\n\n' +
		'var dbImport = require(\'dbjs/lib/_internals/signal-import\');\n\n' +
		exports().map(function (data) {
			return 'dbImport(' + stringify(data[0]) + ', ' + data[1] + ', ' +
				stringify(data[2]) + ', ' + stringify(data[3]) + ');';
		}).join('\n') + '\n';
};
<|endoftext|>